diff --git a/.circleci/config.yml b/.circleci/config.yml index 0ce68b36d90..f5dddad0931 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -90,7 +90,6 @@ jobs: --prefix=/usr \ --enable-phpdbg \ --enable-fpm \ - --enable-opcache \ --with-pdo-mysql=mysqlnd \ --with-mysqli=mysqlnd \ --with-pgsql \ @@ -168,7 +167,6 @@ jobs: no_output_timeout: 30m command: | sapi/cli/php run-tests.php \ - -d zend_extension=opcache.so \ -d opcache.enable_cli=1 \ -d opcache.jit_buffer_size=64M \ -d opcache.jit=tracing \ diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 2bd2f6d94ef..973c9d470dc 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -16,7 +16,7 @@ /.github @TimWolla /build/gen_stub.php @kocsismate -/ext/bcmath @Girgias @nielsdos @SakiTakamachi +/ext/bcmath @nielsdos @SakiTakamachi /ext/curl @adoy /ext/date @derickr /ext/dba @Girgias diff --git a/.github/actions/apk/action.yml b/.github/actions/apk/action.yml index 039fc64a549..da909a36786 100644 --- a/.github/actions/apk/action.yml +++ b/.github/actions/apk/action.yml @@ -6,6 +6,8 @@ runs: run: | set -x + OPCACHE_TLS_TESTS_DEPS="clang gcc binutils-gold lld" + apk update -q apk add \ util-linux \ @@ -53,4 +55,5 @@ runs: postgresql14-dev \ tzdata \ musl-locales \ - musl-locales-lang + musl-locales-lang \ + $OPCACHE_TLS_TESTS_DEPS diff --git a/.github/actions/apt-x32/action.yml b/.github/actions/apt-x32/action.yml index 39ef1df6c2c..14182e76879 100644 --- a/.github/actions/apt-x32/action.yml +++ b/.github/actions/apt-x32/action.yml @@ -6,6 +6,8 @@ runs: run: | set -x + OPCACHE_TLS_TESTS_DEPS="gcc clang lld" + export DEBIAN_FRONTEND=noninteractive dpkg --add-architecture i386 apt-get update -y | true @@ -35,7 +37,6 @@ runs: libssl-dev:i386 \ libwebp-dev:i386 \ libxml2-dev:i386 \ - libxml2-dev:i386 \ libxpm-dev:i386 \ libxslt1-dev:i386 \ firebird-dev:i386 \ @@ -45,4 +46,5 @@ runs: re2c \ unzip \ wget \ - zlib1g-dev:i386 + zlib1g-dev:i386 \ + $OPCACHE_TLS_TESTS_DEPS diff --git a/.github/actions/apt-x64/action.yml b/.github/actions/apt-x64/action.yml index a2ef014c5fa..7ae0a88ff75 100644 --- a/.github/actions/apt-x64/action.yml +++ b/.github/actions/apt-x64/action.yml @@ -10,6 +10,8 @@ runs: run: | set -x + OPCACHE_TLS_TESTS_DEPS="gcc clang lld" + export DEBIAN_FRONTEND=noninteractive # Install sudo in Docker for consistent actions @@ -74,4 +76,5 @@ runs: libqdbm-dev \ libjpeg-dev \ libpng-dev \ - libfreetype6-dev + libfreetype6-dev \ + $OPCACHE_TLS_TESTS_DEPS diff --git a/.github/actions/extra-tests/action.yml b/.github/actions/extra-tests/action.yml new file mode 100644 index 00000000000..05374960640 --- /dev/null +++ b/.github/actions/extra-tests/action.yml @@ -0,0 +1,7 @@ +name: Extra tests +runs: + using: composite + steps: + - shell: sh + run: | + sapi/cli/php run-extra-tests.php diff --git a/.github/actions/freebsd/action.yml b/.github/actions/freebsd/action.yml index 98163d28a82..456d88dd1f8 100644 --- a/.github/actions/freebsd/action.yml +++ b/.github/actions/freebsd/action.yml @@ -3,13 +3,16 @@ inputs: configurationParameters: default: '' required: false + runExtraTests: + default: false + required: false runs: using: composite steps: - name: FreeBSD uses: vmactions/freebsd-vm@v1 with: - release: '13.3' + release: '13.5' usesh: true copyback: false # Temporarily disable sqlite, as FreeBSD ships it with disabled double quotes. We'll need to fix our tests. @@ -17,6 +20,8 @@ runs: prepare: | cd $GITHUB_WORKSPACE + OPCACHE_TLS_TESTS_DEPS="gcc" + kldload accf_http pkg install -y \ autoconf \ @@ -41,9 +46,11 @@ runs: webp \ libavif \ `#sqlite3` \ - curl + curl \ + $OPCACHE_TLS_TESTS_DEPS ./buildconf -f + CC=clang CXX=clang++ \ ./configure \ --prefix=/usr/local \ --enable-debug \ @@ -106,5 +113,8 @@ runs: --offline \ --show-diff \ --show-slow 1000 \ - --set-timeout 120 \ - -d zend_extension=opcache.so + --set-timeout 120 + + if test "${{ inputs.runExtraTests }}" = "true"; then + sapi/cli/php run-extra-tests.php + fi diff --git a/.github/scripts/setup-slapd.sh b/.github/scripts/setup-slapd.sh index fcaa67d0a5f..f6b976783c7 100755 --- a/.github/scripts/setup-slapd.sh +++ b/.github/scripts/setup-slapd.sh @@ -72,6 +72,9 @@ olcTLSCertificateKeyFile: /etc/ldap/ssl/server.key add: olcTLSVerifyClient olcTLSVerifyClient: never - +add: olcTLSProtocolMin +olcTLSProtocolMin: 3.3 +- add: olcAuthzRegexp olcAuthzRegexp: uid=usera,cn=digest-md5,cn=auth cn=usera,dc=my-domain,dc=com - diff --git a/.github/scripts/windows/test_task.bat b/.github/scripts/windows/test_task.bat index 43e7763e702..84ce0acc722 100644 --- a/.github/scripts/windows/test_task.bat +++ b/.github/scripts/windows/test_task.bat @@ -128,7 +128,7 @@ mkdir %PHP_BUILD_DIR%\test_file_cache rem generate php.ini echo extension_dir=%PHP_BUILD_DIR% > %PHP_BUILD_DIR%\php.ini echo opcache.file_cache=%PHP_BUILD_DIR%\test_file_cache >> %PHP_BUILD_DIR%\php.ini -if "%OPCACHE%" equ "1" echo zend_extension=php_opcache.dll >> %PHP_BUILD_DIR%\php.ini +echo opcache.record_warnings=1 >> %PHP_BUILD_DIR%\php.ini rem work-around for some spawned PHP processes requiring OpenSSL and sockets echo extension=php_openssl.dll >> %PHP_BUILD_DIR%\php.ini echo extension=php_sockets.dll >> %PHP_BUILD_DIR%\php.ini diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 6ae972d92e4..3e59990742c 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -17,7 +17,7 @@ jobs: if: github.repository == 'php/php-src' steps: - name: git checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Install dependencies run: pip install -r docs/requirements.txt - name: Check formatting diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 5817c647a87..bbe55e02bbe 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -54,7 +54,7 @@ jobs: runs-on: [self-hosted, gentoo, ppc64] steps: - name: git checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: ref: ${{ inputs.branch }} - name: System info @@ -85,6 +85,8 @@ jobs: with: runTestsParameters: >- --asan -x + - name: Extra tests + uses: ./.github/actions/extra-tests ALPINE: if: inputs.run_alpine name: ALPINE_X64_ASAN_UBSAN_DEBUG_ZTS @@ -93,7 +95,7 @@ jobs: image: 'alpine:3.20.1' steps: - name: git checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: ref: ${{ inputs.branch }} - name: apk @@ -132,8 +134,9 @@ jobs: jitType: tracing runTestsParameters: >- --asan -x - -d zend_extension=opcache.so -d opcache.enable_cli=1 + - name: Extra tests + uses: ./.github/actions/extra-tests - name: Notify Slack if: failure() uses: ./.github/actions/notify-slack @@ -203,7 +206,7 @@ jobs: runs-on: ubuntu-${{ matrix.asan && inputs.asan_ubuntu_version || inputs.ubuntu_version }} steps: - name: git checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: ref: ${{ inputs.branch }} - name: Create MSSQL container @@ -246,14 +249,12 @@ jobs: jitType: tracing runTestsParameters: >- ${{ matrix.run_tests_parameters }} - -d zend_extension=opcache.so -d opcache.enable_cli=1 - name: Test OpCache uses: ./.github/actions/test-linux with: runTestsParameters: >- ${{ matrix.run_tests_parameters }} - -d zend_extension=opcache.so -d opcache.enable_cli=1 - name: Test Function JIT # ASAN frequently timeouts. Each test run takes ~90 minutes, we can @@ -264,8 +265,9 @@ jobs: jitType: function runTestsParameters: >- ${{ matrix.run_tests_parameters }} - -d zend_extension=opcache.so -d opcache.enable_cli=1 + - name: Extra tests + uses: ./.github/actions/extra-tests - name: Verify generated files are up to date uses: ./.github/actions/verify-generated-files - name: Notify Slack @@ -304,7 +306,7 @@ jobs: FIREBIRD_PASSWORD: test steps: - name: git checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: ref: ${{ inputs.branch }} - name: apt @@ -338,14 +340,12 @@ jobs: jitType: tracing runTestsParameters: >- ${{ matrix.run_tests_parameters }} - -d zend_extension=opcache.so -d opcache.enable_cli=1 - name: Test OpCache uses: ./.github/actions/test-linux with: runTestsParameters: >- ${{ matrix.run_tests_parameters }} - -d zend_extension=opcache.so -d opcache.enable_cli=1 - name: Test Function JIT uses: ./.github/actions/test-linux @@ -353,8 +353,9 @@ jobs: jitType: function runTestsParameters: >- ${{ matrix.run_tests_parameters }} - -d zend_extension=opcache.so -d opcache.enable_cli=1 + - name: Extra tests + uses: ./.github/actions/extra-tests - name: Notify Slack if: failure() uses: ./.github/actions/notify-slack @@ -373,7 +374,7 @@ jobs: runs-on: macos-${{ matrix.os }} steps: - name: git checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: ref: ${{ inputs.branch }} - name: brew @@ -398,13 +399,11 @@ jobs: with: jitType: tracing runTestsParameters: >- - -d zend_extension=opcache.so -d opcache.enable_cli=1 - name: Test OpCache uses: ./.github/actions/test-macos with: runTestsParameters: >- - -d zend_extension=opcache.so -d opcache.enable_cli=1 - name: Test Function JIT if: matrix.os != '14' || !matrix.zts @@ -412,8 +411,9 @@ jobs: with: jitType: function runTestsParameters: >- - -d zend_extension=opcache.so -d opcache.enable_cli=1 + - name: Extra tests + uses: ./.github/actions/extra-tests - name: Verify generated files are up to date uses: ./.github/actions/verify-generated-files - name: Notify Slack @@ -449,7 +449,7 @@ jobs: runs-on: ubuntu-22.04 steps: - name: git checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: ref: ${{ inputs.branch }} - name: Create MSSQL container @@ -474,7 +474,6 @@ jobs: with: jitType: tracing runTestsParameters: >- - -d zend_extension=opcache.so -d opcache.enable_cli=1 - uses: codecov/codecov-action@v4 if: ${{ !cancelled() }} @@ -503,7 +502,7 @@ jobs: USE_TRACKED_ALLOC: 1 steps: - name: git checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: ref: ${{ inputs.branch }} - name: apt @@ -528,7 +527,6 @@ jobs: - name: Enable Opcache run: | echo memory_limit=-1 >> /etc/php.d/opcache.ini - echo zend_extension=opcache.so > /etc/php.d/opcache.ini echo opcache.enable_cli=1 >> /etc/php.d/opcache.ini echo opcache.enable=1 >> /etc/php.d/opcache.ini echo opcache.protect_memory=1 >> /etc/php.d/opcache.ini @@ -555,14 +553,17 @@ jobs: repositories="amp cache dns file http parallel parser pipeline process serialization socket sync websocket-client websocket-server" X=0 for repository in $repositories; do - printf "Testing amp/%s\n" "$repository" + echo "::group::$repository" git clone "https://github.com/amphp/$repository.git" "amphp-$repository" --depth 1 cd "amphp-$repository" git rev-parse HEAD php /usr/bin/composer install --no-progress --ignore-platform-req=php+ + EXIT_CODE=0 vendor/bin/phpunit || EXIT_CODE=$? + echo -e "\n::endgroup::" if [ ${EXIT_CODE:-0} -gt 128 ]; then X=1; + echo "Failed" fi cd .. done @@ -586,14 +587,17 @@ jobs: repositories="async cache child-process datagram dns event-loop promise promise-stream promise-timer stream" X=0 for repository in $repositories; do - printf "Testing reactphp/%s\n" "$repository" + echo "::group::$repository" git clone "https://github.com/reactphp/$repository.git" "reactphp-$repository" --depth 1 cd "reactphp-$repository" git rev-parse HEAD php /usr/bin/composer install --no-progress --ignore-platform-req=php+ + EXIT_CODE=0 vendor/bin/phpunit || EXIT_CODE=$? + echo -e "\n::endgroup::" if [ $[EXIT_CODE:-0} -gt 128 ]; then X=1; + echo "Failed" fi cd .. done @@ -618,15 +622,19 @@ jobs: php /usr/bin/composer install --no-progress --ignore-platform-req=php+ php ./phpunit install # Test causes a heap-buffer-overflow but I cannot reproduce it locally... - php -r '$c = file_get_contents("src/Symfony/Component/HtmlSanitizer/Tests/HtmlSanitizerCustomTest.php"); $c = str_replace("public function testSanitizeDeepNestedString()", "/** @group skip */\n public function testSanitizeDeepNestedString()", $c); file_put_contents("src/Symfony/Component/HtmlSanitizer/Tests/HtmlSanitizerCustomTest.php", $c);' + php -r '$c = file_get_contents("src/Symfony/Component/HtmlSanitizer/Tests/HtmlSanitizerCustomTest.php"); $c = str_replace("public function testSanitizeDeepNestedString()", "#[\\PHPUnit\\Framework\\Attributes\\Group('"'"'skip'"'"')]\n public function testSanitizeDeepNestedString()", $c); file_put_contents("src/Symfony/Component/HtmlSanitizer/Tests/HtmlSanitizerCustomTest.php", $c);' # Buggy FFI test in Symfony, see https://github.com/symfony/symfony/issues/47668 - php -r '$c = file_get_contents("src/Symfony/Component/VarDumper/Tests/Caster/FFICasterTest.php"); $c = str_replace("public function testCastNonTrailingCharPointer()", "/** @group skip */\n public function testCastNonTrailingCharPointer()", $c); file_put_contents("src/Symfony/Component/VarDumper/Tests/Caster/FFICasterTest.php", $c);' + php -r '$c = file_get_contents("src/Symfony/Component/VarDumper/Tests/Caster/FFICasterTest.php"); $c = str_replace("public function testCastNonTrailingCharPointer()", "#[\\PHPUnit\\Framework\\Attributes\\Group('"'"'skip'"'"')]\n public function testCastNonTrailingCharPointer()", $c); file_put_contents("src/Symfony/Component/VarDumper/Tests/Caster/FFICasterTest.php", $c);' export SYMFONY_DEPRECATIONS_HELPER=max[total]=999 X=0 for component in $(find src/Symfony -mindepth 2 -type f -name phpunit.xml.dist -printf '%h\n'); do - php ./phpunit $component --exclude-group tty,benchmark,intl-data,transient --exclude-group skip || EXIT_CODE=$? + echo "::group::$component" + EXIT_CODE=0 + php ./phpunit $component --exclude-group tty --exclude-group benchmark --exclude-group intl-data --exclude-group transient --exclude-group skip || EXIT_CODE=$? + echo -e "\n::endgroup::" if [ ${EXIT_CODE:-0} -gt 128 ]; then X=1; + echo "Failed" fi done exit $X @@ -697,7 +705,7 @@ jobs: runs-on: ubuntu-${{ inputs.ubuntu_version }} steps: - name: git checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: ref: ${{ inputs.branch }} - name: Create MSSQL container @@ -719,21 +727,18 @@ jobs: uses: ./.github/actions/test-linux with: runTestsParameters: >- - -d zend_extension=opcache.so -d opcache.enable_cli=1 --file-cache-prime - name: Test File Cache (prime shm, use shm) uses: ./.github/actions/test-linux with: runTestsParameters: >- - -d zend_extension=opcache.so -d opcache.enable_cli=1 --file-cache-use - name: Test File Cache (prime shm, use file) uses: ./.github/actions/test-linux with: runTestsParameters: >- - -d zend_extension=opcache.so -d opcache.enable_cli=1 --file-cache-use -d opcache.file_cache_only=1 @@ -741,7 +746,6 @@ jobs: uses: ./.github/actions/test-linux with: runTestsParameters: >- - -d zend_extension=opcache.so -d opcache.enable_cli=1 --file-cache-prime -d opcache.file_cache_only=1 @@ -749,7 +753,6 @@ jobs: uses: ./.github/actions/test-linux with: runTestsParameters: >- - -d zend_extension=opcache.so -d opcache.enable_cli=1 --file-cache-use -d opcache.file_cache_only=1 @@ -765,7 +768,7 @@ jobs: runs-on: ubuntu-${{ inputs.ubuntu_version }} steps: - name: git checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: ref: ${{ inputs.branch }} - name: apt @@ -843,7 +846,6 @@ jobs: with: runTestsParameters: >- --msan - -d zend_extension=opcache.so -d opcache.enable_cli=1 - name: Verify generated files are up to date uses: ./.github/actions/verify-generated-files @@ -857,7 +859,7 @@ jobs: runs-on: ubuntu-${{ inputs.ubuntu_version }} steps: - name: git checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: ref: ${{ inputs.branch }} - name: apt @@ -907,38 +909,38 @@ jobs: CXX: ccache g++ steps: - name: git checkout PHP - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: path: php ref: ${{ inputs.branch }} - name: git checkout apcu - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: repository: krakjoe/apcu path: apcu - name: git checkout imagick - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: repository: Imagick/imagick path: imagick - name: git checkout memcached - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: repository: php-memcached-dev/php-memcached path: memcached - name: git checkout redis - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: repository: phpredis/phpredis path: redis - name: git checkout xdebug if: false - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: repository: xdebug/xdebug path: xdebug - name: git checkout yaml - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: repository: php/pecl-file_formats-yaml path: yaml @@ -1048,7 +1050,7 @@ jobs: - name: git config run: git config --global core.autocrlf false && git config --global core.eol lf - name: git checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: ref: ${{ inputs.branch }} - name: Setup @@ -1066,9 +1068,10 @@ jobs: - zts: ${{ !inputs.run_freebsd_zts && true || '*never*' }} name: "FREEBSD_${{ matrix.zts && 'ZTS' || 'NTS' }}" runs-on: ubuntu-latest + timeout-minutes: 50 steps: - name: git checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: ref: ${{ inputs.branch }} - name: FreeBSD @@ -1076,3 +1079,4 @@ jobs: with: configurationParameters: >- --${{ matrix.zts && 'enable' || 'disable' }}-zts + runExtraTests: true diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml index 2f82179b90e..b0942b4d700 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/push.yml @@ -82,7 +82,7 @@ jobs: timeout-minutes: 50 steps: - name: git checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: apt uses: ./.github/actions/apt-x64 - name: System info @@ -130,7 +130,6 @@ jobs: with: jitType: tracing runTestsParameters: >- - -d zend_extension=opcache.so -d opcache.enable_cli=1 ${{ matrix.asan && '--asan -x' || '' }} - name: Verify generated files are up to date @@ -167,7 +166,7 @@ jobs: FIREBIRD_PASSWORD: test steps: - name: git checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: apt uses: ./.github/actions/apt-x32 - name: ccache @@ -190,7 +189,6 @@ jobs: with: jitType: tracing runTestsParameters: >- - -d zend_extension=opcache.so -d opcache.enable_cli=1 MACOS_DEBUG_NTS: if: github.repository == 'php/php-src' || github.event_name == 'pull_request' @@ -198,14 +196,14 @@ jobs: fail-fast: false matrix: include: - - os: 14 + - os: 15 arch: ARM64 name: MACOS_${{ matrix.arch }}_DEBUG_NTS runs-on: macos-${{ matrix.os }} timeout-minutes: 50 steps: - name: git checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: brew uses: ./.github/actions/brew - name: ccache @@ -229,7 +227,6 @@ jobs: with: jitType: tracing runTestsParameters: >- - -d zend_extension=opcache.so -d opcache.enable_cli=1 - name: Verify generated files are up to date uses: ./.github/actions/verify-generated-files @@ -253,7 +250,7 @@ jobs: - name: git config run: git config --global core.autocrlf false && git config --global core.eol lf - name: git checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Setup uses: ./.github/actions/setup-windows - name: Build @@ -267,7 +264,7 @@ jobs: timeout-minutes: 50 steps: - name: git checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: fetch-depth: 0 # ASLR can cause a lot of noise due to missed sse opportunities for memcpy @@ -299,7 +296,6 @@ jobs: ./configure \ --disable-debug \ --enable-mbstring \ - --enable-opcache \ --enable-option-checking=fatal \ --enable-sockets \ --enable-werror \ @@ -319,7 +315,6 @@ jobs: sudo mkdir -p /etc/php.d sudo chmod 777 /etc/php.d echo mysqli.default_socket=/var/run/mysqld/mysqld.sock > /etc/php.d/mysqli.ini - echo zend_extension=opcache.so >> /etc/php.d/opcache.ini echo opcache.enable=1 >> /etc/php.d/opcache.ini echo opcache.enable_cli=1 >> /etc/php.d/opcache.ini - name: Setup @@ -331,7 +326,7 @@ jobs: mysql -uroot -proot -e "CREATE USER 'wordpress'@'localhost' IDENTIFIED BY 'wordpress'; FLUSH PRIVILEGES;" mysql -uroot -proot -e "GRANT ALL PRIVILEGES ON *.* TO 'wordpress'@'localhost' WITH GRANT OPTION;" - name: git checkout benchmarking-data - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: repository: php/benchmarking-data ssh-key: ${{ secrets.BENCHMARKING_DATA_DEPLOY_KEY }} @@ -371,8 +366,9 @@ jobs: if: github.repository == 'php/php-src' || github.event_name == 'pull_request' name: FREEBSD runs-on: ubuntu-latest + timeout-minutes: 50 steps: - name: git checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: FreeBSD uses: ./.github/actions/freebsd diff --git a/.github/workflows/real-time-benchmark.yml b/.github/workflows/real-time-benchmark.yml index 9e1fa9fdbe6..65819cd518e 100644 --- a/.github/workflows/real-time-benchmark.yml +++ b/.github/workflows/real-time-benchmark.yml @@ -2,14 +2,94 @@ name: Real-time Benchmark on: schedule: - cron: "30 0 * * *" + workflow_dispatch: + inputs: + pull_request: + description: 'PR number that is going to be benchmarked (e.g. "1234")' + required: true + type: number + jit: + description: 'Whether JIT is benchmarked' + required: false + default: "0" + type: choice + options: + - "0" + - "1" + instruction_count: + description: 'Whether Valgrind instruction count should be measured' + required: true + default: "0" + type: choice + options: + - "0" + - "1" + opcache: + description: 'Whether opcache is enabled for the benchmarked commit' + required: true + default: "1" + type: choice + options: + - "0" + - "1" + - "2" + baseline_opcache: + description: 'Whether opcache is enabled for the baseline commit' + required: true + default: "1" + type: choice + options: + - "0" + - "1" + - "2" permissions: contents: read + pull-requests: write +concurrency: + group: ${{ github.workflow }} + cancel-in-progress: false jobs: REAL_TIME_BENCHMARK: name: REAL_TIME_BENCHMARK - if: github.repository == 'php/php-src' + if: github.repository == 'php/php-src' || github.event_name == 'workflow_dispatch' runs-on: ubuntu-22.04 + env: + REPOSITORY: ${{ github.repository }} + BRANCH: "master" + COMMIT: ${{ github.sha }} + BASELINE_COMMIT: "d5f6e56610c729710073350af318c4ea1b292cfe" + ID: "master" + OPCACHE: ${{ inputs.opcache || '1' }} + BASELINE_OPCACHE: ${{ inputs.baseline_opcache || '2' }} + JIT: ${{ inputs.jit || '1' }} + INSTRUCTION_COUNT: ${{ inputs.instruction_count || '0' }} + YEAR: "" steps: + - name: Setup benchmark environment + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + YEAR="$(date '+%Y')" + echo "YEAR=$YEAR" >> $GITHUB_ENV + + if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then + PR_INFO=$(gh pr view ${{ inputs.pull_request }} --json headRepositoryOwner,headRepository,headRefName,headRefOid,baseRefOid --repo ${{ github.repository }} | jq -r '.headRepositoryOwner.login, .headRepository.name, .headRefName, .headRefOid, .baseRefOid') + + REPOSITORY="$(echo "$PR_INFO" | sed -n '1p')/$(echo "$PR_INFO" | sed -n '2p')" + echo "REPOSITORY=$REPOSITORY" >> $GITHUB_ENV + + BRANCH=$(echo "$PR_INFO" | sed -n '3p') + echo "BRANCH=$BRANCH" >> $GITHUB_ENV + + COMMIT=$(echo "$PR_INFO" | sed -n '4p') + echo "COMMIT=$COMMIT" >> $GITHUB_ENV + + BASELINE_COMMIT=$(echo "$PR_INFO" | sed -n '5p') + echo "BASELINE_COMMIT=$BASELINE_COMMIT" >> $GITHUB_ENV + + echo "ID=benchmarked" >> $GITHUB_ENV + fi + - name: Install dependencies run: | set -ex @@ -23,77 +103,149 @@ jobs: sudo apt-get update -y sudo apt-get install -y terraform=1.5.7-* - name: Checkout benchmark suite - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: repository: 'kocsismate/php-version-benchmarks' ref: 'main' fetch-depth: 1 path: 'php-version-benchmarks' - - name: Checkout php-src - uses: actions/checkout@v4 + - name: Checkout php-src (benchmarked version) + uses: actions/checkout@v5 with: - repository: 'php/php-src' - ref: '${{ github.sha }}' + repository: '${{ env.REPOSITORY }}' + ref: '${{ env.COMMIT }}' fetch-depth: 100 - path: 'php-version-benchmarks/tmp/php_master' + path: 'php-version-benchmarks/tmp/php_${{ env.ID }}' + - name: Checkout php-src (baseline version) + uses: actions/checkout@v5 + with: + repository: '${{ env.REPOSITORY }}' + ref: '${{ env.BASELINE_COMMIT }}' + fetch-depth: 100 + path: 'php-version-benchmarks/tmp/php_baseline' - name: Setup benchmark results run: | git config --global user.name "Benchmark" git config --global user.email "benchmark@php.net" - + rm -rf ./php-version-benchmarks/docs/results - name: Checkout benchmark data - uses: actions/checkout@v4 + if: github.event_name != 'workflow_dispatch' + uses: actions/checkout@v5 with: repository: php/real-time-benchmark-data ssh-key: ${{ secrets.PHP_VERSION_BENCHMARK_RESULTS_DEPLOY_KEY }} path: 'php-version-benchmarks/docs/results' - - name: Set benchmark config + - name: Setup infra config run: | set -e - # Set infrastructure config cp ./php-version-benchmarks/config/infra/aws/x86_64-metal.ini.dist ./php-version-benchmarks/config/infra/aws/x86_64-metal.ini ESCAPED_DOCKER_REGISTRY=$(printf '%s\n' "${{ secrets.PHP_VERSION_BENCHMARK_DOCKER_REGISTRY }}" | sed -e 's/[\/&]/\\&/g') sed -i "s/INFRA_DOCKER_REGISTRY=public.ecr.aws\/abcdefgh/INFRA_DOCKER_REGISTRY=$ESCAPED_DOCKER_REGISTRY/g" ./php-version-benchmarks/config/infra/aws/x86_64-metal.ini + sed -i "s/INFRA_MEASURE_INSTRUCTION_COUNT=0/INFRA_MEASURE_INSTRUCTION_COUNT=${{ env.INSTRUCTION_COUNT }}/g" ./php-version-benchmarks/config/infra/aws/x86_64-metal.ini cp ./php-version-benchmarks/build/infrastructure/config/aws.tfvars.dist ./php-version-benchmarks/build/infrastructure/config/aws.tfvars sed -i 's/access_key = ""/access_key = "${{ secrets.PHP_VERSION_BENCHMARK_AWS_ACCESS_KEY }}"/g' ./php-version-benchmarks/build/infrastructure/config/aws.tfvars sed -i 's/secret_key = ""/secret_key = "${{ secrets.PHP_VERSION_BENCHMARK_AWS_SECRET_KEY }}"/g' ./php-version-benchmarks/build/infrastructure/config/aws.tfvars + sed -i 's/github_token = ""/github_token = "${{ secrets.GITHUB_TOKEN }}"/g' ./php-version-benchmarks/build/infrastructure/config/aws.tfvars + - name: Setup PHP config - baseline PHP version + run: | + set -e - YEAR="$(date '+%Y')" - DATABASE="./php-version-benchmarks/docs/results/$YEAR/database.tsv" + BASELINE_SHORT_SHA="$(echo "${{ env.BASELINE_COMMIT }}" | cut -c1-4)" + + cat << EOF > ./php-version-benchmarks/config/php/baseline.ini + PHP_NAME="PHP - baseline@$BASELINE_SHORT_SHA" + PHP_ID=php_baseline + + PHP_REPO=https://github.com/${{ env.REPOSITORY }}.git + PHP_BRANCH=${{ env.BRANCH }} + PHP_COMMIT=${{ env.BASELINE_COMMIT }} + + PHP_OPCACHE=${{ env.BASELINE_OPCACHE }} + PHP_JIT=0 + EOF + - name: Setup PHP config - baseline PHP version with JIT + if: github.event_name == 'workflow_dispatch' && inputs.jit == '1' + run: | + set -e + + BASELINE_SHORT_SHA="$(echo "${{ env.BASELINE_COMMIT }}" | cut -c1-4)" + + cat << EOF > ./php-version-benchmarks/config/php/baseline_jit.ini + PHP_NAME="PHP - baseline@$BASELINE_SHORT_SHA (JIT)" + PHP_ID=php_baseline_jit + + PHP_REPO=https://github.com/${{ env.REPOSITORY }}.git + PHP_BRANCH=${{ env.BRANCH }} + PHP_COMMIT=${{ env.BASELINE_COMMIT }} + + PHP_OPCACHE=${{ env.BASELINE_OPCACHE }} + PHP_JIT=${{ env.JIT }} + EOF + + git clone ./php-version-benchmarks/tmp/php_baseline/ ./php-version-benchmarks/tmp/php_baseline_jit + - name: Setup PHP config - previous PHP version + if: github.event_name != 'workflow_dispatch' + run: | + set -e + + DATABASE="./php-version-benchmarks/docs/results/${{ env.YEAR }}/database.tsv" if [ -f "$DATABASE" ]; then LAST_RESULT_SHA="$(tail -n 2 "$DATABASE" | head -n 1 | cut -f 6)" else YESTERDAY="$(date -d "-2 day 23:59:59" '+%Y-%m-%d %H:%M:%S')" - LAST_RESULT_SHA="$(cd ./php-version-benchmarks/tmp/php_master/ && git --no-pager log --until="$YESTERDAY" -n 1 --pretty='%H')" + LAST_RESULT_SHA="$(cd ./php-version-benchmarks/tmp/php_${{ env.ID }}/ && git --no-pager log --until="$YESTERDAY" -n 1 --pretty='%H')" fi - BASELINE_SHA="d5f6e56610c729710073350af318c4ea1b292cfe" - BASELINE_SHORT_SHA="$(echo "$BASELINE_SHA" | cut -c1-4)" + cat << EOF > ./php-version-benchmarks/config/php/previous.ini + PHP_NAME="PHP - previous ${{ env.BRANCH }}" + PHP_ID=php_previous - # Set config for the baseline PHP version - cp ./php-version-benchmarks/config/php/master.ini.dist ./php-version-benchmarks/config/php/master_baseline.ini - sed -i 's/PHP_NAME="PHP - master"/PHP_NAME="PHP - baseline@'"$BASELINE_SHORT_SHA"'"/g' ./php-version-benchmarks/config/php/master_baseline.ini - sed -i "s/PHP_ID=php_master/PHP_ID=php_master_baseline/g" ./php-version-benchmarks/config/php/master_baseline.ini - sed -i "s/PHP_COMMIT=/PHP_COMMIT=$BASELINE_SHA/g" ./php-version-benchmarks/config/php/master_baseline.ini + PHP_REPO=https://github.com/${{ env.REPOSITORY }}.git + PHP_BRANCH=${{ env.BRANCH }} + PHP_COMMIT=$LAST_RESULT_SHA - # Set config for the previous PHP version - cp ./php-version-benchmarks/config/php/master.ini.dist ./php-version-benchmarks/config/php/master_last.ini - sed -i 's/PHP_NAME="PHP - master"/PHP_NAME="PHP - previous master"/g' ./php-version-benchmarks/config/php/master_last.ini - sed -i "s/PHP_ID=php_master/PHP_ID=php_master_previous/g" ./php-version-benchmarks/config/php/master_last.ini - sed -i "s/PHP_COMMIT=/PHP_COMMIT=$LAST_RESULT_SHA/g" ./php-version-benchmarks/config/php/master_last.ini + PHP_OPCACHE=1 + PHP_JIT=0 + EOF + - name: Setup PHP config - benchmarked PHP version + run: | + set -e - # Set config for the current PHP version - cp ./php-version-benchmarks/config/php/master.ini.dist ./php-version-benchmarks/config/php/master_now.ini - sed -i "s/PHP_COMMIT=/PHP_COMMIT=${{ github.sha }}/g" ./php-version-benchmarks/config/php/master_now.ini + cat << EOF > ./php-version-benchmarks/config/php/this.ini + PHP_NAME="PHP - ${{ env.BRANCH }}" + PHP_ID=php_${{ env.ID }} - # Set config for current PHP version with JIT - git clone ./php-version-benchmarks/tmp/php_master/ ./php-version-benchmarks/tmp/php_master_jit - cp ./php-version-benchmarks/config/php/master_jit.ini.dist ./php-version-benchmarks/config/php/master_now_jit.ini - sed -i "s/PHP_COMMIT=/PHP_COMMIT=${{ github.sha }}/g" ./php-version-benchmarks/config/php/master_now_jit.ini + PHP_REPO=https://github.com/${{ env.REPOSITORY }}.git + PHP_BRANCH=${{ env.BRANCH }} + PHP_COMMIT=${{ env.COMMIT }} + + PHP_OPCACHE=${{ env.OPCACHE }} + PHP_JIT=0 + EOF + - name: Setup PHP config - benchmarked PHP version with JIT + if: env.JIT == '1' + run: | + set -e + + cat << EOF > ./php-version-benchmarks/config/php/this_jit.ini + PHP_NAME="PHP - ${{ env.BRANCH }} (JIT)" + PHP_ID=php_${{ env.ID }}_jit + + PHP_REPO=https://github.com/${{ env.REPOSITORY }}.git + PHP_BRANCH=${{ env.BRANCH }} + PHP_COMMIT=${{ env.COMMIT }} + + PHP_OPCACHE=${{ env.OPCACHE }} + PHP_JIT=${{ env.JIT }} + EOF + + git clone ./php-version-benchmarks/tmp/php_${{ env.ID }}/ ./php-version-benchmarks/tmp/php_${{ env.ID }}_jit + - name: Setup test config + run: | + set -e - # Set test configs cp ./php-version-benchmarks/config/test/1_laravel.ini.dist ./php-version-benchmarks/config/test/1_laravel.ini cp ./php-version-benchmarks/config/test/2_symfony_main.ini.dist ./php-version-benchmarks/config/test/2_symfony_main.ini cp ./php-version-benchmarks/config/test/4_wordpress.ini.dist ./php-version-benchmarks/config/test/4_wordpress.ini @@ -102,6 +254,7 @@ jobs: - name: Run benchmark run: ./php-version-benchmarks/benchmark.sh run aws - name: Store results + if: github.repository == 'php/php-src' && github.event_name != 'workflow_dispatch' run: | set -ex @@ -117,6 +270,21 @@ jobs: fi git commit -m "Add result for ${{ github.repository }}@${{ github.sha }}" git push + - name: Upload artifact + if: github.event_name == 'workflow_dispatch' + uses: actions/upload-artifact@v4 + with: + name: results + path: ./php-version-benchmarks/docs/results/${{ env.YEAR }} + retention-days: 30 + - name: Comment results + if: github.event_name == 'workflow_dispatch' + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + cd ./php-version-benchmarks/tmp/php_${{ env.ID }} + NEWEST_RESULT_DIRECTORY=$(ls -td ${{ github.workspace }}/php-version-benchmarks/docs/results/${{ env.YEAR }}/*/ | head -1) + gh pr comment ${{ inputs.pull_request }} --body-file "${NEWEST_RESULT_DIRECTORY}result.md" --repo ${{ github.repository }} - name: Cleanup if: always() run: | diff --git a/.github/workflows/root.yml b/.github/workflows/root.yml index 96943a8cfb2..16418b1aa1d 100644 --- a/.github/workflows/root.yml +++ b/.github/workflows/root.yml @@ -13,7 +13,7 @@ jobs: outputs: branches: ${{ steps.set-matrix.outputs.branches }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 with: # Set fetch-depth to 0 to clone the full repository # including all branches. This is required to find diff --git a/.gitignore b/.gitignore index 1e92e88fb77..b76b5a787ca 100644 --- a/.gitignore +++ b/.gitignore @@ -131,6 +131,7 @@ config.h.in /sapi/cgi/php-cgi /sapi/fpm/php-fpm /sapi/phpdbg/phpdbg +/sapi/fuzzer/php-fuzz-* /scripts/php-config /scripts/phpize php diff --git a/NEWS b/NEWS index d35d34b84e9..09d9b87aafa 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,198 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| -?? ??? ????, PHP 8.5.0alpha2 +?? ??? ????, PHP 8.5.0beta2 + +- Core: + . Fixed bug GH-18850 (Repeated inclusion of file with __halt_compiler() + triggers "Constant already defined" warning). (ilutov) + . Fixed bug GH-19476 (pipe operator fails to correctly handle returning + by reference). (alexandre-daubois) + +- ODBC: + . Remove ODBCVER and assume ODBC 3.5. (Calvin Buckley) + +- OpenSSL: + . Implement #81724 (openssl_cms_encrypt only allows specific ciphers). + (Jakub Zelenka) + +- Session: + . Added support for partitioned cookies. (nielsdos) + +- Standard: + . Fixed bug GH-16649 (UAF during array_splice). (alexandre-daubois) + . Passing integers outside the interval [0, 255] to chr() is now deprecated. + (Girgias) + . Added support for partitioned cookies. (nielsdos) + +14 Aug 2025, PHP 8.5.0beta1 + +- Core: + . Non-canonical cast names (boolean), (integer), (double), and (binary) have + been deprecated. (Girgias) + . The $exclude_disabled parameter of the get_defined_functions() function has + been deprecated, as it no longer has any effect since PHP 8.0. (Girgias) + . Terminating case statements with a semicolon instead of a colon has + been deprecated. (theodorejb) + . The backtick operator as an alias for shell_exec() has been deprecated. + (timwolla) + . Returning null from __debugInfo() has been deprecated. (DanielEScherzer) + . Support #[\Override] on properties. (Jiří Pudil) + +- Curl: + . The curl_close() function has been deprecated. (DanielEScherzer) + . The curl_share_close() function has been deprecated. (DanielEScherzer) + +- Date: + . The DATE_RFC7231 and DateTimeInterface::RFC7231 constants have been + deprecated. (jorgsowa) + +- DOM: + . Fixed bug GH-18877 (\Dom\HTMLDocument querySelectorAll selecting only the + first when using ~ and :has). (nielsdos, lexborisov) + +- FileInfo + . The finfo_close() function has been deprecated. (timwolla) + . The $context parameter of the finfo_buffer() function has been deprecated + as it is ignored. (Girgias) + +- GD: + . The imagedestroy() function has been deprecated. (DanielEScherzer) + +- Intl: + . Intl's internal error mechanism has been modernized so that it + indicates more accurately which call site caused what error. + Moreover, some ext/date exceptions have been wrapped inside a + IntlException now. (Girgias) + . The intl.error_level INI setting has been deprecated. (Girgias) + +- MySQLi: + . The mysqli_execute() alias function has been deprecated. (timwolla) + +- OpenSSL: + . Fixed bug GH-19369 (8.5 | Regression in openssl_sign() - support for alias + algorithms appears to be broken). (Jakub Zelenka) + . The $key_length parameter for openssl_pkey_derive() has been deprecated. + (Girgias) + . Implement #80495 (Enable to set padding in openssl_(sign|verify). + (Jakub Zelenka) + . Implement #47728 (openssl_pkcs7_sign ignores new openssl flags). + (Jakub Zelenka) + +- PDO: + . The "uri:" DSN scheme has been deprecated due to security concerns with + DSNs coming from remote URIs. (timwolla) + +- Reflection: + . Fixed bug GH-17927 (Reflection: have some indication of property hooks in + `_property_string()`). (DanielEScherzer) + . The setAccessible() methods of various Reflection objects have been + deprecated, as those no longer have an effect. (timwolla) + . ReflectionClass::getConstant() for constants that do not exist has been + deprecated. (DanielEScherzer) + . ReflectionProperty::getDefaultValue() for properties without default values + has been deprecated. (DanielEScherzer) + +- SPL: + . Unregistering all autoloaders by passing the spl_autoload_call() function + as a callback argument to spl_autoload_unregister() has been deprecated. + Instead if this is needed, one should iterate over the return value of + spl_autoload_functions() and call spl_autoload_unregister() on each + value. (Girgias) + . The SplObjectStorage::contains(), SplObjectStorage::attach(), and + SplObjectStorage::detach() methods have been deprecated in favour of + SplObjectStorage::offsetExists(), SplObjectStorage::offsetSet(), and + SplObjectStorage::offsetUnset() respectively. (Girgias) + +- Standard: + . The socket_set_timeout() alias function has been deprecated. (timwolla) + . Passing null to to readdir(), rewinddir(), and closedir() to use the last + opened directory has been deprecated. (Girgias) + . Fixed bug GH-19153 (#[\Attribute] validation should error on + trait/interface/enum/abstract class). (DanielEScherzer) + +- XML: + . The xml_parser_free() function has been deprecated. (DanielEScherzer) + +31 Jul 2025, PHP 8.5.0alpha4 + +- Core: + . Add clone-with support to the clone() function. (timwolla, edorian) + . Fix support for non-userland stream notifiers. (timwolla) + . Added PHP_BUILD_PROVIDER constant. (timwolla) + . Fixed bug GH-19305 (Operands may be being released during comparison). + (Arnaud) + . Fixed bug GH-19306 (Generator can be resumed while fetching next value from + delegated Generator). (Arnaud) + . Fixed bug GH-19326 (Calling Generator::throw() on a running generator with + a non-Generator delegate crashes). (Arnaud) + +- Curl: + . Add support for CURLINFO_CONN_ID in curl_getinfo() (thecaliskan) + . Add support for CURLINFO_QUEUE_TIME_T in curl_getinfo() (thecaliskan) + . Add support for CURLOPT_SSL_SIGNATURE_ALGORITHMS. (Ayesh Karunaratne) + +- FPM: + . Make FPM access log limit configurable using log_limit. (Jakub Zelenka) + +- GD: + . Fix incorrect comparison with result of php_stream_can_cast(). (Girgias) + +- Intl: + . Fix return value on failure for resourcebundle count handler. (Girgias) + . Fixed bug GH-19307 (PGO builds of shared ext-intl are broken). (cmb) + +- OPcache: + . Disallow changing opcache.memory_consumption when SHM is already set up. + (timwolla) + . Fixed bug GH-15074 (Compiling opcache statically into ZTS PHP fails). + (Arnaud) + . Make OPcache non-optional (Arnaud, timwolla) + . Fixed bug GH-17422 (OPcache bypasses the user-defined error handler for + deprecations). (Arnaud, timwolla) + . Fixed bug GH-19301 (opcache build failure). (Remi) + +- OpenSSL: + . Add $digest_algo parameter to openssl_public_encrypt() and + openssl_private_decrypt() functions. (Jakub Zelenka) + +- POSIX: + . posix_kill and posix_setpgid throws a ValueError on invalid process_id. + (David Carlier) + . posix_setpgid throws a ValueError on invalid process_group_id, + posix_setrlimit throws a ValueError on invalid soft_limit and hard_limit + arguments. (David Carlier) + +- Reflection: + . Fixed bug GH-19187 (ReflectionNamedType::getName() prints nullable type when + retrieved from ReflectionProperty::getSettableType()). (ilutov) + +- Session: + . Fixed GH-19197: build broken with ZEND_STRL usage with memcpy + when implemented as macro. (David Carlier) + +- Soap: + . Fixed bug GH-19226 (Segfault when spawning new thread in soap extension). + (Florian Engelhardt) + +- Sockets: + . socket_set_option for multicast context throws a ValueError + when the socket family is not of AF_INET/AF_INET6 family. (David Carlier) + +- Standard: + . Add HEIF/HEIC support to getimagesize. (Benstone Zhang) + . Implement #71517 (Implement SVG support for getimagesize() and friends). + (nielsdos) + . Optimized PHP html_entity_decode function. (Artem Ukrainskiy) + . Minor optimization to array_chunk(). (nielsdos) + +- URI: + . Empty host handling is fixed. (Máté Kocsis) + . Error handling of Uri\WhatWg\Url::withHost() is fixed when the input + contains a port. Now, it triggers an exception; previously, the error + was silently swallowed. (Máté Kocsis) + . Support empty URIs with Uri\Rfc3986\Uri. (timwolla) + +17 Jul 2025, PHP 8.5.0alpha2 - Core: . Fix OSS-Fuzz #427814452 (pipe compilation fails with assert). @@ -41,7 +233,7 @@ PHP NEWS - CURL: . Added CURLFOLLOW_ALL, CURLFOLLOW_OBEYCODE and CURLFOLLOW_FIRSTONLY - values for CURLOPT_FOLLOLOCATION curl_easy_setopt option. (David Carlier) + values for CURLOPT_FOLLOWLOCATION curl_easy_setopt option. (David Carlier) - COM: . Fixed property access of PHP objects wrapped in variant. (cmb) @@ -135,8 +327,8 @@ PHP NEWS . Added grapheme_levenshtein() function. (Yuya Hamada) . Added Locale::addLikelySubtags/Locale::minimizeSubtags to handle adding/removing likely subtags to a locale. (David Carlier) - . Added IntlListFormatter class to format a list of items with a locale - , operands types and units. (BogdanUngureanu) + . Added IntlListFormatter class to format a list of items with a locale, + operands types and units. (BogdanUngureanu) . Fixed bug GH-18566 ([intl] Weird numeric sort in Collator). (nielsdos) - LDAP: @@ -160,7 +352,7 @@ PHP NEWS - OpenSSL: . Added openssl.libctx INI that allows to select the OpenSSL library context - type and convert verious parts of the extension to use the custom libctx. + type and convert various parts of the extension to use the custom libctx. (Jakub Zelenka) - Output: @@ -170,7 +362,7 @@ PHP NEWS . Extend pcntl_waitid with rusage parameter. (vrza) - PCRE: - . Upgraded to pre2lib from 10.44 to 10.45. (nielsdos) + . Upgraded to pcre2lib from 10.44 to 10.45. (nielsdos) . Remove PCRE2_EXTRA_ALLOW_LOOKAROUND_BSK from pcre compile options. (mvorisek) @@ -216,8 +408,9 @@ PHP NEWS (DanielEScherzer) . Fixed bug GH-12856 (ReflectionClass::getStaticPropertyValue() returns UNDEF zval for uninitialized typed properties). (nielsdos) - . Fixed bug GH-15766 (ReflectionClass::toString() should have better output + . Fixed bug GH-15766 (ReflectionClass::__toString() should have better output for enums). (DanielEScherzer) + . Added ReflectionProperty::getMangledName() method. (alexandre-daubois) - Session: . session_start() throws a ValueError on option argument if not a hashmap @@ -278,7 +471,7 @@ PHP NEWS (David Carlier) - Sodium: - . Fix overall theorical overflows on zend_string buffer allocations. + . Fix overall theoretical overflows on zend_string buffer allocations. (David Carlier/nielsdos) - Sqlite: @@ -307,7 +500,7 @@ PHP NEWS (cmb) - Tests: - . Allow to shuffle tests even in non-parallell mode. (dhuang00) + . Allow to shuffle tests even in non-parallel mode. (dhuang00) - Tidy: . tidy::__construct/parseFile/parseString methods throw an exception if diff --git a/UPGRADING b/UPGRADING index 0847ad009e7..d208a4620d7 100644 --- a/UPGRADING +++ b/UPGRADING @@ -44,6 +44,15 @@ PHP 8.5 UPGRADE NOTES . Traits are now bound before the parent class. This is a subtle behavioral change, but should more closely match user expectations, demonstrated by GH-15753 and GH-16198. + . Errors emitted during compilation and class linking are now always delayed + and handled after compilation or class linking. Fatal errors emitted during + compilation or class linking cause any delayed errors to be handled + immediately, without calling user-defined error handlers. + . Exceptions thrown by user-defined error handlers when handling class linking + errors are not promoted to fatal errors anymore and do not prevent linking. + . Applying #[\Attribute] to an abstract class, enum, interface, or trait triggers + an error during compilation. Previously, the attribute could be added, but when + ReflectionAttribute::newInstance() was called an error would be thrown. - DOM: . Cloning a DOMNamedNodeMap, DOMNodeList, Dom\NamedNodeMap, Dom\NodeList, @@ -71,6 +80,20 @@ PHP 8.5 UPGRADE NOTES . Calling the mysqli constructor on an already-constructed object is now no longer possible and throws an Error. +- ODBC: + . ODBC now assumes that at least ODBC 3.5 functionality is available. The + ODBCVER definition and build system flags to control it have been removed. + +- Opcache: + . The Opcache extension is now always built into the PHP binary and is always + loaded. The INI directives opcache.enable and opcache.enable_cli are still + honored. + The --enable-opcache/--disable-opcache configure flags have been removed, + and the build does not produce opcache.so or php_opcache.dll objects + anymore. + Using zend_extension=opcache.so or zend_extension=php_opcache.dll INI + directives will emit a warning. + - PCNTL: . pcntl_exec() now throws ValueErrors when entries of the $args parameter contain null bytes. @@ -159,6 +182,8 @@ PHP 8.5 UPGRADE NOTES RFC: https://wiki.php.net/rfc/pipe-operator-v3 . Constructor property promotion can now be used for final properties. RFC: https://wiki.php.net/rfc/final_promotion + . #[\Override] can now be applied to properties. + RFC: https://wiki.php.net/rfc/override_properties - Curl: . Added support for share handles that are persisted across multiple PHP @@ -188,6 +213,18 @@ PHP 8.5 UPGRADE NOTES first redirect thus if there is any follow up redirect, it won't go any further. CURLFOLLOW_ALL is equivalent to setting CURLOPT_FOLLOWLOCATION to true. + . Added support for CURLINFO_CONN_ID (libcurl >= 8.2.0) to the curl_getinfo() + function. This constant allows retrieving the unique ID of the connection + used by a cURL transfer. It is primarily useful when connection reuse or + connection pooling logic is needed in PHP-level applications. When + curl_getinfo() returns an array, this value is available as the "conn_id" key. + . Added support for CURLINFO_QUEUE_TIME_T (libcurl >= 8.6.0) to the curl_getinfo() + function. This constant allows retrieving the time (in microseconds) that the + request spent in libcurl’s connection queue before it was sent. + This value can also be retrieved by passing CURLINFO_QUEUE_TIME_T to the + curl_getinfo() $option parameter. + . Added support for CURLOPT_SSL_SIGNATURE_ALGORITHMS to specify the signature + algorithms to use for TLS. - DOM: . Added Dom\Element::$outerHTML. @@ -216,6 +253,11 @@ PHP 8.5 UPGRADE NOTES Pdo_Sqlite::EXPLAIN_MODE_PREPARED, Pdo_Sqlite::EXPLAIN_MODE_EXPLAIN, Pdo_Sqlite::EXPLAIN_MODE_EXPLAIN_QUERY_PLAN. +- Session: + . session_set_cookie_params(), session_get_cookie_params(), and session_start() + now support partitioned cookies via the "partitioned" key. + RFC: https://wiki.php.net/rfc/CHIPS + - SOAP: . Enumeration cases are now dumped in __getTypes(). . Implemented request #61105: @@ -234,6 +276,16 @@ PHP 8.5 UPGRADE NOTES process was terminated unexpectedly. In such cases, a warning is emitted and the function returns false. Previously, these errors were silently ignored. This change affects only the sendmail transport. + . getimagesize() now supports HEIF/HEIC images. + . getimagesize() now supports SVG images when ext-libxml is also loaded. + Similarly, image_type_to_extension() and image_type_to_mime_type() + now also handle IMAGETYPE_SVG. + . The array returned by getimagesize() now has two additional entries: + "width_unit" and "height_unit" to indicate in which units the dimensions + are expressed. These units are px by default. They are not necessarily + the same (just to give one example: one may be cm and the other may be px). + . setcookie() and setrawcookie() now support the "partitioned" key. + RFC: https://wiki.php.net/rfc/CHIPS - XSL: . The $namespace argument of XSLTProcessor::getParameter(), @@ -260,6 +312,7 @@ PHP 8.5 UPGRADE NOTES - FPM: . FPM with httpd ProxyPass decodes the full script path. Added fastcgi.script_path_encoded INI setting to prevent this new behavior. + . FPM access log limit now respects log_limit value. ======================================== 4. Deprecated Functionality @@ -277,12 +330,115 @@ PHP 8.5 UPGRADE NOTES one will still be used. If a user output handler returns a non-string and produces output, the warning about producing an output is emitted first. RFC: https://wiki.php.net/rfc/deprecations_php_8_4 + . Non-canonical cast names (boolean), (integer), (double), and (binary) have + been deprecated, use (bool), (int), (float), and (string) respectively. + RFC: https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_non-standard_cast_names + . The $exclude_disabled parameter of the get_defined_functions() function has + been deprecated, as it no longer has any effect since PHP 8.0. + RFC: https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_the_exclude_disabled_parameter_of_get_defined_functions + . Terminating case statements with a semicolon instead of a colon has + been deprecated. + RFC: https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_semicolon_after_case_in_switch_statement + . The backtick operator as an alias for shell_exec() has been deprecated. + RFC: https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_backticks_as_an_alias_for_shell_exec + . Returning null from __debugInfo() has been deprecated. + Return an empty array instead. + RFC: https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_debuginfo_returning_null + +- Curl: + . The curl_close() function has been deprecated, as CurlHandle objects are + freed automatically. + RFC: https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_curl_close + . The curl_share_close() function has been deprecated, as CurlShareHandle + objects are freed automatically. + RFC: https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_curl_share_close + +- Date: + . The DATE_RFC7231 and DateTimeInterface::RFC7231 constants have been + deprecated. This is because the associated timezone is ignored and always + uses GMT. + RFC: https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_date_rfc7231_and_datetimeinterfacerfc7231 + +- FileInfo: + . The finfo_close() function has been deprecated. + As finfo objects are freed automatically. + RFC: https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_finfo_close + . The $context parameter of the finfo_buffer() function has been deprecated + as it is ignored. + RFC: https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_the_context_parameter_for_finfo_buffer + +- GD: + . The imagedestroy() function has been deprecated, as GdImage objects are + freed automatically. + RFC: https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_imagedestroy - Hash: . The MHASH_* constants have been deprecated. These have been overlooked when the mhash*() function family has been deprecated per https://wiki.php.net/rfc/deprecations_php_8_1#mhash_function_family +- Intl: + . The intl.error_level INI setting has been deprecated. + Errors should either be checked manually or exceptions should be enabled + by using the intl.use_exceptions INI setting. + RFC: https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_intlerror_level_ini_setting + +- MySQLi: + . The mysqli_execute() alias function has been deprecated. + Use mysqli_stmt_execute() instead. + RFC: https://wiki.php.net/rfc/deprecations_php_8_5#formally_deprecate_mysqli_execute + +- OpenSSL: + . The $key_length parameter for openssl_pkey_derive() has been deprecated. + This is because it is either ignored, or truncates the key, which can be + a vulnerability. + RFC: https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_key_length_parameter_of_openssl_pkey_derive + +- PDO: + . The "uri:" DSN scheme has been deprecated due to security concerns with + DSNs coming from remote URIs. + RFC: https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_pdo_s_urischeme + +- Reflection: + . The setAccessible() methods of various Reflection objects have been + deprecated, as those no longer have an effect. + RFC: https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_reflectionsetaccessible + . Calling ReflectionClass::getConstant() for constants that do not exist has + been deprecated. + RFC: https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_reflectionclassgetconstant_for_missing_constants + . Calling ReflectionProperty::getDefaultValue() for properties without default + values has been deprecated. + RFC: https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_reflectionpropertygetdefaultvalue_for_properties_without_default_values + +- SPL: + . Unregistering all autoloaders by passing the spl_autoload_call() function + as a callback argument to spl_autoload_unregister() has been deprecated. + Instead if this is needed, one should iterate over the return value of + spl_autoload_functions() and call spl_autoload_unregister() on each value. + RFC: https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_passing_spl_autoload_call_to_spl_autoload_unregister + . The SplObjectStorage::contains(), SplObjectStorage::attach(), and + SplObjectStorage::detach() methods have been deprecated in favour of + SplObjectStorage::offsetExists(), SplObjectStorage::offsetSet(), and + SplObjectStorage::offsetUnset() respectively. + RFC: https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_splobjectstoragecontains_splobjectstorageattach_and_splobjectstoragedetach + +- Standard: + . The socket_set_timeout() alias function has been deprecated. + Use stream_set_timeout() instead. + RFC: https://wiki.php.net/rfc/deprecations_php_8_5#formally_deprecate_socket_set_timeout + . Passing null to to readdir(), rewinddir(), and closedir() to use the last + opened directory has been deprecated. Provide the last opened directory + explicitly instead. + RFC: https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_passing_null_to_readdir_rewinddir_and_closedir + . Passing integers outside the interval [0, 255] to chr() is now deprecated. + This is because a byte can only hold a value within this interval. + RFC: https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_passing_integers_outside_the_interval_0_255_to_chr + +- XML: + . The xml_parser_free() function has been deprecated, as XMLParser objects + are freed automatically. + RFC: https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_xml_parser_free + ======================================== 5. Changed Functions ======================================== @@ -307,6 +463,15 @@ PHP 8.5 UPGRADE NOTES - libxml: . libxml_set_external_entity_loader() now has a formal return type of true. +- OpenSSL: + . openssl_public_encrypt() and openssl_private_decrypt() have new parameter + $digest_algo that allows specifying hash digest algorithm for OEAP padding. + . openssl_sign() and openssl_verify() have new parameter $padding to allow + using more secure RSA PSS padding. + . openssl_cms_encrypt() $cipher_algo parameter can be a string with the + cipher name. That allows to use more algorithms including AES GCM cipher + algorithms for auth enveloped data. + - PCNTL: . pcntl_exec() now has a formal return type of false. . pcntl_waitid() takes an additional resource_usage argument to @@ -339,16 +504,28 @@ PHP 8.5 UPGRADE NOTES an invalid file descriptor. . posix_fpathconf checks invalid file descriptors and sets last_error to EBADF and raises an E_WARNING message. + . posix_kill throws a ValueError when the process_id argument is lower + or greater than what supports the platform (signed integer or long + range), posix_setpgid throws a ValueError when the process_id or + the process_group_id is lower than zero or greater than + what supports the platform. + . posix_setrlimit throws a ValueError when the hard_limit of soft_limit + argument are lower than -1 or if soft_limit is greater than hard_limit. - Reflection: - . The output of ReflectionClass::toString() for enums has changed to + . The output of ReflectionClass::__toString() for enums has changed to better indicate that the class is an enum, and that the enum cases are enum cases rather than normal class constants. + . The output of ReflectionProperty::__toString() for properties with + hooks has changed to indicate what hooks the property has, whether those + hooks are final, and whether the property is virtual. This also affects + the output of ReflectionClass::__toString() when a class contains hooked + properties. - Session: . session_start is stricter in regard to the option argument. It throws a ValueError if the whole is not a hashmap or - a TypeError if read_on_close value is not a valid type + a TypeError if read_and_close value is not a valid type compatible with int. - SNMP: @@ -361,7 +538,7 @@ PHP 8.5 UPGRADE NOTES - Sockets: . socket_create_listen, socket_bind and socket_sendto throw a ValueError if the port is lower than 0 or greater than 65535, - also if any of the hints array entry is indexes numerically. + and also if any of the hints array entries are indexed numerically. . socket_addrinfo_lookup throws a TypeError if any of the hints values cannot be cast to int and can throw a ValueError if any of these values overflow. @@ -371,6 +548,8 @@ PHP 8.5 UPGRADE NOTES . socket_create/socket_bind can create AF_PACKET family sockets. . socket_getsockname gets the interface index and its string representation with AF_PACKET socket. + . socket_set_option with multicast context throws a ValueError + when the created socket is not of AF_INET/AF_INET6 family. - Tidy: . tidy::__construct/parseFile/parseString now throws a ValueError @@ -396,8 +575,10 @@ PHP 8.5 UPGRADE NOTES . get_exception_handler() allows retrieving the current user-defined exception handler function. RFC: https://wiki.php.net/rfc/get-error-exception-handler - . The clone language construct is now a function. + . The clone language construct is now a function and supports reassigning + (readonly) properties during cloning via the new $withProperties parameter. RFC: https://wiki.php.net/rfc/clone_with_v2 + . Added Closure::getCurrent() to receive currently executing closure. - Curl: . curl_multi_get_handles() allows retrieving all CurlHandles current @@ -423,6 +604,9 @@ PHP 8.5 UPGRADE NOTES . Added grapheme_levenshtein() function. RFC: https://wiki.php.net/rfc/grapheme_levenshtein +- Opcache: + . Added opcache_is_script_cached_in_file_cache(). + - Pdo\Sqlite: . Added support for Pdo\Sqlite::setAuthorizer(), which is the equivalent of SQLite3::setAuthorizer(). The only interface difference is that the @@ -440,6 +624,7 @@ PHP 8.5 UPGRADE NOTES ReflectionConstant::getExtensionName() were introduced. . ReflectionConstant::getAttributes() was introduced. RFC: https://wiki.php.net/rfc/attributes-on-constants + . ReflectionProperty::getMangledName() was introduced. - Sqlite: . Sqlite3Stmt::busy to check if a statement had been fetched @@ -458,6 +643,13 @@ PHP 8.5 UPGRADE NOTES across multiple PHP requests. RFC: https://wiki.php.net/rfc/curl_share_persistence_improvement +- URI: + . Uri\UriException, Uri\InvalidUriException, Uri\UriComparisonMode, + Uri\Rfc3986\Uri, Uri\WhatWg\InvalidUrlException, + Uri\WhatWg\UrlValidationErrorType, Uri\WhatWg\UrlValidationError, + and Uri\WhatWg\Url are added. + RFC: https://wiki.php.net/rfc/url_parsing_api + ======================================== 8. Removed Extensions and SAPIs ======================================== @@ -472,17 +664,33 @@ PHP 8.5 UPGRADE NOTES CURLFOLLOW_FIRSTONLY. - Fileinfo: - . Upgraded to file 5.46. + . Upgraded file from 5.45 to 5.46. . The return type of finfo_close() has been changed to true, rather than bool. +- Intl: + . Intl's internal error mechanism has been modernized so that it + indicates more accurately which call site caused what error. + Moreover, some ext/date exceptions have been wrapped inside a + IntlException now. + - Lexbor: . An always enabled lexbor extension is added. It contains the lexbor library that was separated from ext/dom for being reused among other extensions. The new extension is not directly exposed to userland. +- Opcache: + . The Opcache extension is now always built into the PHP binary and is always + loaded. The INI directives opcache.enable and opcache.enable_cli are still + honored. + +- URI: + . An always enabled uri extension is added that can be used for handling + URIs and URLs according to RFC 3986 and WHATWG URL. + RFC: https://wiki.php.net/rfc/url_parsing_api + - PCRE: - . Upgraded to pcre2lib from 10.44 to 10.45. + . Upgraded pcre2lib from 10.44 to 10.45. - PDO_Sqlite: . Increased minimum release version support from 3.7.7 to 3.7.17. @@ -498,11 +706,14 @@ PHP 8.5 UPGRADE NOTES - Core: . PHP_BUILD_DATE. + . PHP_BUILD_PROVIDER. - Curl: . CURLINFO_USED_PROXY. . CURLINFO_HTTPAUTH_USED. . CURLINFO_PROXYAUTH_USED. + . CURLINFO_CONN_ID. + . CURLINFO_QUEUE_TIME_T. . CURLOPT_INFILESIZE_LARGE. . CURLFOLLOW_ALL. . CURLFOLLOW_OBEYCODE. @@ -512,6 +723,13 @@ PHP 8.5 UPGRADE NOTES . DECIMAL_COMPACT_SHORT. . DECIMAL_COMPACT_LONG. +- OpenSSL: + . OPENSSL_PKCS1_PSS_PADDING + . PKCS7_NOSMIMECAP + . PKCS7_CRLFEOL + . PKCS7_NOCRL + . PKCS7_NO_DUAL_CONTENT + - POSIX: . POSIX_SC_OPEN_MAX. @@ -535,6 +753,9 @@ PHP 8.5 UPGRADE NOTES . T_VOID_CAST. . T_PIPE. +- Standard: + . IMAGETYPE_SVG when libxml is loaded. + ======================================== 11. Changes to INI File Handling ======================================== @@ -543,6 +764,11 @@ PHP 8.5 UPGRADE NOTES . Added fatal_error_backtraces to control whether fatal errors should include a backtrace. RFC: https://wiki.php.net/rfc/error_backtraces_v2 + . Added startup-only max_memory_limit INI setting to control the maximum + memory_limit that may be configured at startup or runtime. Exceeding this + value emits a warning, unless set to -1, and sets memory_limit to the + current max_memory_limit instead. + ML discussion: https://externals.io/message/127108 - Opcache: . Added opcache.file_cache_read_only to support a read-only @@ -557,11 +783,14 @@ PHP 8.5 UPGRADE NOTES . The default value of opcache.jit_hot_loop is now 61 (a prime) to prevent it from being a multiple of loop iteration counts. It is recommended that this parameter is set to a prime number. + . Changing opcache.memory_consumption when OPcache SHM is already set up + will now correctly report a failure instead of silently doing nothing and + showing misleading values in PHPInfo. - OpenSSL: - Added openssl.libctx to select the OpenSSL library context type. Either - custom libctx for each thread can be used or a single global (default) - libctx is used. + . Added openssl.libctx to select the OpenSSL library context type. Either + custom libctx for each thread can be used or a single global (default) + libctx is used. ======================================== 12. Windows Support @@ -638,6 +867,10 @@ PHP 8.5 UPGRADE NOTES . The parts of the code that used SSE2 have been adapted to use SIMD with ARM NEON as well. +- Opcache: + . Improved performance of fetching TLS variables in JIT'ed code in non-Glibc + builds. + - ReflectionProperty: . Improved performance of the following methods: getValue(), getRawValue(), isInitialized(), setValue(), setRawValue(). @@ -652,6 +885,7 @@ PHP 8.5 UPGRADE NOTES . Improved unpack() performance with nameless repetitions by avoiding creating temporary strings and reparsing them. . Improved pack() performance. + . Minor improvements in array_chunk() performance. - XMLReader: . Improved property access performance. diff --git a/UPGRADING.INTERNALS b/UPGRADING.INTERNALS index 7a14a4907ea..b7396941e50 100644 --- a/UPGRADING.INTERNALS +++ b/UPGRADING.INTERNALS @@ -23,6 +23,15 @@ PHP 8.5 INTERNALS UPGRADE NOTES the user side when requiring libphp.so, by using dlmopen with LM_ID_NEWLM instead of dlopen. RTLD_DEEPBIND is still enabled when the Apache SAPI is in use. + . The ptr field of the php_stream_notifier struct is now a void* instead + of a zval. If the zval was used to store IS_PTR values only, the + extra layer of indirection can be removed. In other cases a zval can + be heap-allocated and stored in the pointer as a minimal change to keep + compatibility. + +- Hash + . Hash functions now use proper hash_spec_result enum for return values + instead of using SUCCESS and FAILURE. - Zend . Added zend_safe_assign_to_variable_noref() function to safely assign @@ -66,6 +75,15 @@ PHP 8.5 INTERNALS UPGRADE NOTES * zend_register_string_constant() * zend_register_stringl_constant() . EG(fake_scope) now is a _const_ zend_class_entry*. + . zend_begin_record_errors() or EG(record_errors)=true cause errors to be + delayed. Before, errors would be recorded but not delayed. + . zend_mm_refresh_key_child() must be called on any zend_mm_heap inherited + from the parent process after a fork(). + . HASH_KEY_IS_* constants have been moved in the zend_hash_key_type enum. + +- standard + . ext/standard/php_smart_string.h and ext/standard/php_smart_string_public.h + were removed. Use the corresponding headers in Zend/ instead. ======================== 2. Build system changes @@ -83,11 +101,12 @@ PHP 8.5 INTERNALS UPGRADE NOTES that appropriate build rules are created. - Unix build system changes - . libdir is properly set when --libdir (ex: /usr/lib64) and --with-libdir (ex lib64) + . libdir is properly set when --libdir (ex: /usr/lib64) and --with-libdir (ex: lib64) configure options are used to ${libdir}/php (ex: /usr/lib64/php) . PHP_ODBC_CFLAGS, PHP_ODBC_LFLAGS, PHP_ODBC_LIBS, PHP_ODBC_TYPE preprocessor macros defined by ext/odbc are now defined in php_config.h instead of the build-defs.h header. + . Autoconf macro AX_CHECK_COMPILE_FLAG updated to serial 11. . Autoconf macro PHP_AP_EXTRACT_VERSION has been removed. . Autoconf macro PHP_BUILD_THREAD_SAFE has been removed (set enable_zts manually). @@ -129,11 +148,24 @@ PHP 8.5 INTERNALS UPGRADE NOTES . The php_std_date() function has been removed. Use php_format_date() with the "D, d M Y H:i:s \\G\\M\\T" format instead. . Added php_url_encode_to_smart_str() to encode a URL to a smart_str buffer. + . The functionality of getimagesize(), image_type_to_mime_type(), + and image_type_to_extension() is now extensible using the internal APIs + php_image_register_handler() and php_image_unregister_handler() in + php_image.h. ======================== 4. OpCode changes ======================== +* New ZEND_DECLARE_ATTRIBUTED_CONST is used when a global constant is declared + with `const` and has attributes; this opcode is used *instead* of the + ZEND_DECLARE_CONST, and in addition to the name of the constant and the + value to use, has a ZEND_OP_DATA with a pointer to the compiled attributes. + ======================== 5. SAPI changes ======================== + +- SAPIs must now call php_child_init() after a fork. If php-src code was + executed in other threads than the one initiating the fork, + refresh_memory_manager() must be called in every such thread. diff --git a/Zend/Optimizer/block_pass.c b/Zend/Optimizer/block_pass.c index 96a0e81f038..275c519d431 100644 --- a/Zend/Optimizer/block_pass.c +++ b/Zend/Optimizer/block_pass.c @@ -420,6 +420,14 @@ static void zend_optimize_block(zend_basic_block *block, zend_op_array *op_array } break; + case ZEND_EXT_STMT: + if (opline->op1_type & (IS_TMP_VAR|IS_VAR)) { + /* Variable will be deleted later by FREE, so we can't optimize it */ + Tsource[VAR_NUM(opline->op1.var)] = NULL; + break; + } + break; + case ZEND_CASE: case ZEND_CASE_STRICT: case ZEND_COPY_TMP: diff --git a/Zend/Optimizer/zend_optimizer.h b/Zend/Optimizer/zend_optimizer.h index 16bfd75520d..43a0f60a232 100644 --- a/Zend/Optimizer/zend_optimizer.h +++ b/Zend/Optimizer/zend_optimizer.h @@ -98,6 +98,10 @@ ZEND_API int zend_optimizer_register_pass(zend_optimizer_pass_t pass); ZEND_API void zend_optimizer_unregister_pass(int idx); zend_result zend_optimizer_startup(void); zend_result zend_optimizer_shutdown(void); + +typedef void (*zend_op_array_func_t)(zend_op_array *, void *context); +void zend_foreach_op_array(zend_script *script, zend_op_array_func_t func, void *context); + END_EXTERN_C() #endif diff --git a/Zend/Optimizer/zend_optimizer_internal.h b/Zend/Optimizer/zend_optimizer_internal.h index a1fc57092d1..896fe8fb472 100644 --- a/Zend/Optimizer/zend_optimizer_internal.h +++ b/Zend/Optimizer/zend_optimizer_internal.h @@ -128,7 +128,4 @@ int sccp_optimize_op_array(zend_optimizer_ctx *ctx, zend_op_array *op_array, zen int dce_optimize_op_array(zend_op_array *op_array, zend_optimizer_ctx *optimizer_ctx, zend_ssa *ssa, bool reorder_dtor_effects); zend_result zend_ssa_escape_analysis(const zend_script *script, zend_op_array *op_array, zend_ssa *ssa); -typedef void (*zend_op_array_func_t)(zend_op_array *, void *context); -void zend_foreach_op_array(zend_script *script, zend_op_array_func_t func, void *context); - #endif diff --git a/Zend/Optimizer/zend_ssa.c b/Zend/Optimizer/zend_ssa.c index 4c09e5e105b..886bb467b44 100644 --- a/Zend/Optimizer/zend_ssa.c +++ b/Zend/Optimizer/zend_ssa.c @@ -22,6 +22,7 @@ #include "zend_ssa.h" #include "zend_dump.h" #include "zend_inference.h" +#include "zend_worklist.h" #include "Optimizer/zend_optimizer_internal.h" static bool dominates(const zend_basic_block *blocks, int a, int b) { @@ -816,7 +817,7 @@ ZEND_API int zend_ssa_rename_op(const zend_op_array *op_array, const zend_op *op } /* }}} */ -static zend_result zend_ssa_rename(const zend_op_array *op_array, uint32_t build_flags, zend_ssa *ssa, int *var, int n) /* {{{ */ +static void zend_ssa_rename_in_block(const zend_op_array *op_array, uint32_t build_flags, zend_ssa *ssa, int *var, int n) /* {{{ */ { zend_basic_block *blocks = ssa->cfg.blocks; zend_ssa_block *ssa_blocks = ssa->blocks; @@ -824,15 +825,6 @@ static zend_result zend_ssa_rename(const zend_op_array *op_array, uint32_t build int ssa_vars_count = ssa->vars_count; int i, j; zend_op *opline, *end; - int *tmp = NULL; - ALLOCA_FLAG(use_heap = 0); - - // FIXME: Can we optimize this copying out in some cases? - if (blocks[n].next_child >= 0) { - tmp = do_alloca(sizeof(int) * (op_array->last_var + op_array->T), use_heap); - memcpy(tmp, var, sizeof(int) * (op_array->last_var + op_array->T)); - var = tmp; - } if (ssa_blocks[n].phis) { zend_ssa_phi *phi = ssa_blocks[n].phis; @@ -916,22 +908,90 @@ static zend_result zend_ssa_rename(const zend_op_array *op_array, uint32_t build } ssa->vars_count = ssa_vars_count; +} +/* }}} */ - j = blocks[n].children; - while (j >= 0) { - // FIXME: Tail call optimization? - if (zend_ssa_rename(op_array, build_flags, ssa, var, j) == FAILURE) - return FAILURE; - j = blocks[j].next_child; +static zend_result zend_ssa_rename(const zend_op_array *op_array, uint32_t build_flags, zend_ssa *ssa, int *var, int n) +{ + /* The worklist contains block numbers, encoded as positive or negative value. + * Positive values indicate that the variable rename still needs to happen for the block. + * Negative values indicate the variable rename was done and all children were handled too. + * In that case, we will clean up. + * Because block 0 is valid, we bias the block numbers by adding 1 such that we can distinguish + * positive and negative values in all cases. */ + zend_worklist_stack work; + ALLOCA_FLAG(work_use_heap); + ZEND_WORKLIST_STACK_ALLOCA(&work, ssa->cfg.blocks_count, work_use_heap); + zend_worklist_stack_push(&work, n + 1); + + /* This is used to backtrack the right version of the renamed variables to use. */ + ALLOCA_FLAG(save_vars_use_heap); + unsigned int save_vars_top = 0; + int **save_vars = do_alloca(sizeof(int *) * (ssa->cfg.blocks_count + 1), save_vars_use_heap); + save_vars[0] = var; + + while (work.len) { + n = zend_worklist_stack_pop(&work); + + /* Enter state: perform SSA variable rename */ + if (n > 0) { + n--; + + // FIXME: Can we optimize this copying out in some cases? + int *new_var; + if (ssa->cfg.blocks[n].next_child >= 0) { + new_var = emalloc(sizeof(int) * (op_array->last_var + op_array->T)); + memcpy(new_var, save_vars[save_vars_top], sizeof(int) * (op_array->last_var + op_array->T)); + save_vars[++save_vars_top] = new_var; + } else { + new_var = save_vars[save_vars_top]; + } + + zend_ssa_rename_in_block(op_array, build_flags, ssa, new_var, n); + + int j = ssa->cfg.blocks[n].children; + if (j >= 0) { + /* Push backtrack state */ + zend_worklist_stack_push(&work, -(n + 1)); + + /* Push children in enter state */ + unsigned int child_count = 0; + int len_prior = work.len; + do { + zend_worklist_stack_push(&work, j + 1); + j = ssa->cfg.blocks[j].next_child; + child_count++; + } while (j >= 0); + + /* Reverse block order to maintain SSA variable number order given in previous PHP versions, + * but the data structure doesn't allow reverse dominator tree traversal. */ + for (unsigned int i = 0; i < child_count / 2; i++) { + int tmp = work.buf[len_prior + i]; + work.buf[len_prior + i] = work.buf[work.len - 1 - i]; + work.buf[work.len - 1 - i] = tmp; + } + } else { + /* Leafs jump directly to backtracking */ + goto backtrack; + } + } + /* Leave state: backtrack */ + else { + n = -n; + n--; +backtrack:; + if (ssa->cfg.blocks[n].next_child >= 0) { + efree(save_vars[save_vars_top]); + save_vars_top--; + } + } } - if (tmp) { - free_alloca(tmp, use_heap); - } + free_alloca(save_vars, save_vars_use_heap); + ZEND_WORKLIST_STACK_FREE_ALLOCA(&work, work_use_heap); return SUCCESS; } -/* }}} */ ZEND_API zend_result zend_build_ssa(zend_arena **arena, const zend_script *script, const zend_op_array *op_array, uint32_t build_flags, zend_ssa *ssa) /* {{{ */ { diff --git a/Zend/Zend.m4 b/Zend/Zend.m4 index 69a546afce4..20116eb3e53 100644 --- a/Zend/Zend.m4 +++ b/Zend/Zend.m4 @@ -193,28 +193,21 @@ AS_VAR_IF([GCC], [yes], dnl Check if compiler supports -Wno-clobbered (only GCC). AX_CHECK_COMPILE_FLAG([-Wno-clobbered], - [CFLAGS="-Wno-clobbered $CFLAGS"],, - [-Werror]) + [CFLAGS="-Wno-clobbered $CFLAGS"]) dnl Check for support for implicit fallthrough level 1, also add after previous dnl CFLAGS as level 3 is enabled in -Wextra. AX_CHECK_COMPILE_FLAG([-Wimplicit-fallthrough=1], - [CFLAGS="$CFLAGS -Wimplicit-fallthrough=1"],, - [-Werror]) + [CFLAGS="$CFLAGS -Wimplicit-fallthrough=1"]) AX_CHECK_COMPILE_FLAG([-Wduplicated-cond], - [CFLAGS="-Wduplicated-cond $CFLAGS"],, - [-Werror]) + [CFLAGS="-Wduplicated-cond $CFLAGS"]) AX_CHECK_COMPILE_FLAG([-Wlogical-op], - [CFLAGS="-Wlogical-op $CFLAGS"],, - [-Werror]) + [CFLAGS="-Wlogical-op $CFLAGS"]) AX_CHECK_COMPILE_FLAG([-Wformat-truncation], - [CFLAGS="-Wformat-truncation $CFLAGS"],, - [-Werror]) + [CFLAGS="-Wformat-truncation $CFLAGS"]) AX_CHECK_COMPILE_FLAG([-Wstrict-prototypes], - [CFLAGS="-Wstrict-prototypes $CFLAGS"],, - [-Werror]) + [CFLAGS="-Wstrict-prototypes $CFLAGS"]) AX_CHECK_COMPILE_FLAG([-fno-common], - [CFLAGS="-fno-common $CFLAGS"],, - [-Werror]) + [CFLAGS="-fno-common $CFLAGS"]) ZEND_CHECK_ALIGNMENT ZEND_CHECK_SIGNALS diff --git a/Zend/tests/014.inc b/Zend/tests/014.inc deleted file mode 100644 index 69c9bc07902..00000000000 --- a/Zend/tests/014.inc +++ /dev/null @@ -1,3 +0,0 @@ - diff --git a/Zend/tests/022.phpt b/Zend/tests/abstract_method_optional_params.phpt similarity index 100% rename from Zend/tests/022.phpt rename to Zend/tests/abstract_method_optional_params.phpt diff --git a/Zend/tests/arginfo_zpp_mismatch.inc b/Zend/tests/arginfo_zpp_mismatch.inc index 5b2711fdb63..2eb8905f5d4 100644 --- a/Zend/tests/arginfo_zpp_mismatch.inc +++ b/Zend/tests/arginfo_zpp_mismatch.inc @@ -9,6 +9,7 @@ function skipFunction($function): bool { /* terminates script */ || $function === 'exit' || $function === 'die' + || $function === 'zend_trigger_bailout' /* intentionally violate invariants */ || $function === 'zend_create_unterminated_string' || $function === 'zend_test_array_return' diff --git a/Zend/tests/032.phpt b/Zend/tests/array_append_by_reference.phpt similarity index 100% rename from Zend/tests/032.phpt rename to Zend/tests/array_append_by_reference.phpt diff --git a/Zend/tests/031.phpt b/Zend/tests/array_append_reading_error.phpt similarity index 100% rename from Zend/tests/031.phpt rename to Zend/tests/array_append_reading_error.phpt diff --git a/Zend/tests/array_unpack/gh19303.phpt b/Zend/tests/array_unpack/gh19303.phpt new file mode 100644 index 00000000000..af594c3740c --- /dev/null +++ b/Zend/tests/array_unpack/gh19303.phpt @@ -0,0 +1,11 @@ +--TEST-- +GH-19303 (Unpacking empty packed array into uninitialized array causes assertion failure) +--FILE-- + +--EXPECT-- +array(0) { +} diff --git a/Zend/tests/assert/expect_012.phpt b/Zend/tests/assert/expect_012.phpt index 71e2f96e629..77a5e485284 100644 --- a/Zend/tests/assert/expect_012.phpt +++ b/Zend/tests/assert/expect_012.phpt @@ -5,12 +5,12 @@ zend.assertions=1 assert.exception=1 --FILE-- diff --git a/Zend/tests/029.phpt b/Zend/tests/assign_array_object_property.phpt similarity index 100% rename from Zend/tests/029.phpt rename to Zend/tests/assign_array_object_property.phpt diff --git a/Zend/tests/026.phpt b/Zend/tests/assign_property_null_object.phpt similarity index 100% rename from Zend/tests/026.phpt rename to Zend/tests/assign_property_null_object.phpt diff --git a/Zend/tests/asymmetric_visibility/gh19044.phpt b/Zend/tests/asymmetric_visibility/gh19044.phpt new file mode 100644 index 00000000000..253e315d5b9 --- /dev/null +++ b/Zend/tests/asymmetric_visibility/gh19044.phpt @@ -0,0 +1,24 @@ +--TEST-- +GH-19044: Protected properties must be scoped according to their prototype (protected(set) on non-hooked property) +--FILE-- + 42; } +} + +class C1 extends P { + public protected(set) mixed $foo = 1; +} + +class C2 extends P { + public protected(set) mixed $foo; + + static function foo($c) { return $c->foo += 1; } +} + +var_dump(C2::foo(new C1)); + +?> +--EXPECT-- +int(43) diff --git a/Zend/tests/attributes/Attribute/Attribute_on_abstract.phpt b/Zend/tests/attributes/Attribute/Attribute_on_abstract.phpt new file mode 100644 index 00000000000..547946c4e13 --- /dev/null +++ b/Zend/tests/attributes/Attribute/Attribute_on_abstract.phpt @@ -0,0 +1,12 @@ +--TEST-- +#[Attribute] on an abstract class +--FILE-- + +--EXPECTF-- +Fatal error: Cannot apply #[\Attribute] to abstract class Demo in %s on line %d diff --git a/Zend/tests/attributes/Attribute/Attribute_on_enum.phpt b/Zend/tests/attributes/Attribute/Attribute_on_enum.phpt new file mode 100644 index 00000000000..c5545054dcf --- /dev/null +++ b/Zend/tests/attributes/Attribute/Attribute_on_enum.phpt @@ -0,0 +1,12 @@ +--TEST-- +#[Attribute] on an enum +--FILE-- + +--EXPECTF-- +Fatal error: Cannot apply #[\Attribute] to enum Demo in %s on line %d diff --git a/Zend/tests/attributes/Attribute/Attribute_on_interface.phpt b/Zend/tests/attributes/Attribute/Attribute_on_interface.phpt new file mode 100644 index 00000000000..4b9a87a2395 --- /dev/null +++ b/Zend/tests/attributes/Attribute/Attribute_on_interface.phpt @@ -0,0 +1,12 @@ +--TEST-- +#[Attribute] on an interface +--FILE-- + +--EXPECTF-- +Fatal error: Cannot apply #[\Attribute] to interface Demo in %s on line %d diff --git a/Zend/tests/attributes/Attribute/Attribute_on_trait.phpt b/Zend/tests/attributes/Attribute/Attribute_on_trait.phpt new file mode 100644 index 00000000000..7ea05543baa --- /dev/null +++ b/Zend/tests/attributes/Attribute/Attribute_on_trait.phpt @@ -0,0 +1,12 @@ +--TEST-- +#[Attribute] on a trait +--FILE-- + +--EXPECTF-- +Fatal error: Cannot apply #[\Attribute] to trait Demo in %s on line %d diff --git a/Zend/tests/attributes/allow_dynamic_properties_on_enum.phpt b/Zend/tests/attributes/allow_dynamic_properties_on_enum.phpt index b9ab745be9a..f1ce8b055b0 100644 --- a/Zend/tests/attributes/allow_dynamic_properties_on_enum.phpt +++ b/Zend/tests/attributes/allow_dynamic_properties_on_enum.phpt @@ -8,4 +8,4 @@ enum Test {} ?> --EXPECTF-- -Fatal error: Cannot apply #[AllowDynamicProperties] to enum Test in %s on line %d +Fatal error: Cannot apply #[\AllowDynamicProperties] to enum Test in %s on line %d diff --git a/Zend/tests/attributes/allow_dynamic_properties_on_interface.phpt b/Zend/tests/attributes/allow_dynamic_properties_on_interface.phpt index 0428256a18e..16440a385db 100644 --- a/Zend/tests/attributes/allow_dynamic_properties_on_interface.phpt +++ b/Zend/tests/attributes/allow_dynamic_properties_on_interface.phpt @@ -8,4 +8,4 @@ interface Test {} ?> --EXPECTF-- -Fatal error: Cannot apply #[AllowDynamicProperties] to interface Test in %s on line %d +Fatal error: Cannot apply #[\AllowDynamicProperties] to interface Test in %s on line %d diff --git a/Zend/tests/attributes/allow_dynamic_properties_on_trait.phpt b/Zend/tests/attributes/allow_dynamic_properties_on_trait.phpt index 9636dc03141..bd18b3e71c8 100644 --- a/Zend/tests/attributes/allow_dynamic_properties_on_trait.phpt +++ b/Zend/tests/attributes/allow_dynamic_properties_on_trait.phpt @@ -8,4 +8,4 @@ trait Test {} ?> --EXPECTF-- -Fatal error: Cannot apply #[AllowDynamicProperties] to trait Test in %s on line %d +Fatal error: Cannot apply #[\AllowDynamicProperties] to trait Test in %s on line %d diff --git a/Zend/tests/attributes/override/properties_01.phpt b/Zend/tests/attributes/override/properties_01.phpt new file mode 100644 index 00000000000..d83f935f834 --- /dev/null +++ b/Zend/tests/attributes/override/properties_01.phpt @@ -0,0 +1,39 @@ +--TEST-- +#[\Override]: Properties +--FILE-- + +--EXPECT-- +Done diff --git a/Zend/tests/attributes/override/properties_02.phpt b/Zend/tests/attributes/override/properties_02.phpt new file mode 100644 index 00000000000..aefe84f150d --- /dev/null +++ b/Zend/tests/attributes/override/properties_02.phpt @@ -0,0 +1,15 @@ +--TEST-- +#[\Override]: Properties: No parent class. +--FILE-- + +--EXPECTF-- +Fatal error: C::$c has #[\Override] attribute, but no matching parent property exists in %s on line %d diff --git a/Zend/tests/attributes/override/properties_03.phpt b/Zend/tests/attributes/override/properties_03.phpt new file mode 100644 index 00000000000..c2b2ea0acc2 --- /dev/null +++ b/Zend/tests/attributes/override/properties_03.phpt @@ -0,0 +1,21 @@ +--TEST-- +#[\Override]: Properties: No parent class, but child implements matching interface. +--FILE-- + +--EXPECTF-- +Fatal error: P::$i has #[\Override] attribute, but no matching parent property exists in %s on line %d diff --git a/Zend/tests/attributes/override/properties_04.phpt b/Zend/tests/attributes/override/properties_04.phpt new file mode 100644 index 00000000000..142a1d0c640 --- /dev/null +++ b/Zend/tests/attributes/override/properties_04.phpt @@ -0,0 +1,21 @@ +--TEST-- +#[\Override]: Properties: No parent class, but child implements matching interface (2). +--FILE-- + +--EXPECTF-- +Fatal error: P::$i has #[\Override] attribute, but no matching parent property exists in %s on line %d diff --git a/Zend/tests/attributes/override/properties_05.phpt b/Zend/tests/attributes/override/properties_05.phpt new file mode 100644 index 00000000000..71113dad60e --- /dev/null +++ b/Zend/tests/attributes/override/properties_05.phpt @@ -0,0 +1,26 @@ +--TEST-- +#[\Override]: Properties: No parent interface. +--FILE-- + +--EXPECTF-- +Fatal error: I::$i has #[\Override] attribute, but no matching parent property exists in %s on line %d diff --git a/Zend/tests/attributes/override/properties_06.phpt b/Zend/tests/attributes/override/properties_06.phpt new file mode 100644 index 00000000000..66309ac625c --- /dev/null +++ b/Zend/tests/attributes/override/properties_06.phpt @@ -0,0 +1,15 @@ +--TEST-- +#[\Override]: Properties: On trait. +--FILE-- + +--EXPECT-- +Done diff --git a/Zend/tests/attributes/override/properties_07.phpt b/Zend/tests/attributes/override/properties_07.phpt new file mode 100644 index 00000000000..ae9ed4b8dbf --- /dev/null +++ b/Zend/tests/attributes/override/properties_07.phpt @@ -0,0 +1,19 @@ +--TEST-- +#[\Override]: Properties: On used trait without parent property. +--FILE-- + +--EXPECTF-- +Fatal error: Foo::$t has #[\Override] attribute, but no matching parent property exists in %s on line %d diff --git a/Zend/tests/attributes/override/properties_08.phpt b/Zend/tests/attributes/override/properties_08.phpt new file mode 100644 index 00000000000..c976dcecdc1 --- /dev/null +++ b/Zend/tests/attributes/override/properties_08.phpt @@ -0,0 +1,23 @@ +--TEST-- +#[\Override]: Properties: On used trait with interface property. +--FILE-- + +--EXPECT-- +Done diff --git a/Zend/tests/attributes/override/properties_09.phpt b/Zend/tests/attributes/override/properties_09.phpt new file mode 100644 index 00000000000..85970ba11a4 --- /dev/null +++ b/Zend/tests/attributes/override/properties_09.phpt @@ -0,0 +1,19 @@ +--TEST-- +#[\Override]: Properties: Parent property is private, child property is public. +--FILE-- + +--EXPECTF-- +Fatal error: C::$p has #[\Override] attribute, but no matching parent property exists in %s on line %d diff --git a/Zend/tests/attributes/override/properties_10.phpt b/Zend/tests/attributes/override/properties_10.phpt new file mode 100644 index 00000000000..ce1d7f46fd5 --- /dev/null +++ b/Zend/tests/attributes/override/properties_10.phpt @@ -0,0 +1,19 @@ +--TEST-- +#[\Override]: Properties: Parent property is private, child property is private. +--FILE-- + +--EXPECTF-- +Fatal error: C::$p has #[\Override] attribute, but no matching parent property exists in %s on line %d diff --git a/Zend/tests/attributes/override/properties_11.phpt b/Zend/tests/attributes/override/properties_11.phpt new file mode 100644 index 00000000000..354e718505d --- /dev/null +++ b/Zend/tests/attributes/override/properties_11.phpt @@ -0,0 +1,19 @@ +--TEST-- +#[\Override]: Properties: Parent property is protected, child property is public. +--FILE-- + +--EXPECT-- +Done diff --git a/Zend/tests/attributes/override/properties_12.phpt b/Zend/tests/attributes/override/properties_12.phpt new file mode 100644 index 00000000000..351ed26b0af --- /dev/null +++ b/Zend/tests/attributes/override/properties_12.phpt @@ -0,0 +1,19 @@ +--TEST-- +#[\Override]: Properties: Parent property is protected, child property is protected. +--FILE-- + +--EXPECT-- +Done diff --git a/Zend/tests/attributes/override/properties_13.phpt b/Zend/tests/attributes/override/properties_13.phpt new file mode 100644 index 00000000000..d9ab0a6b9a2 --- /dev/null +++ b/Zend/tests/attributes/override/properties_13.phpt @@ -0,0 +1,21 @@ +--TEST-- +#[\Override]: Properties: Redeclared trait property. +--FILE-- + +--EXPECTF-- +Fatal error: C::$t has #[\Override] attribute, but no matching parent property exists in %s on line %d diff --git a/Zend/tests/attributes/override/properties_14.phpt b/Zend/tests/attributes/override/properties_14.phpt new file mode 100644 index 00000000000..4e098c6d721 --- /dev/null +++ b/Zend/tests/attributes/override/properties_14.phpt @@ -0,0 +1,25 @@ +--TEST-- +#[\Override]: Properties: Redeclared trait property with interface. +--FILE-- + +--EXPECT-- +Done diff --git a/Zend/tests/attributes/override/properties_15.phpt b/Zend/tests/attributes/override/properties_15.phpt new file mode 100644 index 00000000000..37d46b2a170 --- /dev/null +++ b/Zend/tests/attributes/override/properties_15.phpt @@ -0,0 +1,19 @@ +--TEST-- +#[\Override]: Properties: Valid anonymous class. +--FILE-- + +--EXPECT-- +Done diff --git a/Zend/tests/attributes/override/properties_16.phpt b/Zend/tests/attributes/override/properties_16.phpt new file mode 100644 index 00000000000..57ea17818c4 --- /dev/null +++ b/Zend/tests/attributes/override/properties_16.phpt @@ -0,0 +1,21 @@ +--TEST-- +#[\Override]: Properties: Invalid anonymous class. +--FILE-- + +--EXPECTF-- +Fatal error: I@anonymous::$c has #[\Override] attribute, but no matching parent property exists in %s on line %d diff --git a/Zend/tests/attributes/override/properties_17.phpt b/Zend/tests/attributes/override/properties_17.phpt new file mode 100644 index 00000000000..389d66035ea --- /dev/null +++ b/Zend/tests/attributes/override/properties_17.phpt @@ -0,0 +1,16 @@ +--TEST-- +#[\Override]: Properties: Static property no parent class. +--FILE-- + +--EXPECTF-- +Fatal error: C::$c has #[\Override] attribute, but no matching parent property exists in %s on line %d diff --git a/Zend/tests/attributes/override/properties_18.phpt b/Zend/tests/attributes/override/properties_18.phpt new file mode 100644 index 00000000000..66731a69f8e --- /dev/null +++ b/Zend/tests/attributes/override/properties_18.phpt @@ -0,0 +1,19 @@ +--TEST-- +#[\Override]: Properties: Static property. +--FILE-- + +--EXPECT-- +Done diff --git a/Zend/tests/attributes/override/properties_19.phpt b/Zend/tests/attributes/override/properties_19.phpt new file mode 100644 index 00000000000..1844664e3ca --- /dev/null +++ b/Zend/tests/attributes/override/properties_19.phpt @@ -0,0 +1,21 @@ +--TEST-- +#[\Override]: Properties: valid promoted property +--FILE-- + +--EXPECT-- +Done diff --git a/Zend/tests/attributes/override/properties_20.phpt b/Zend/tests/attributes/override/properties_20.phpt new file mode 100644 index 00000000000..fcfbfa727c8 --- /dev/null +++ b/Zend/tests/attributes/override/properties_20.phpt @@ -0,0 +1,17 @@ +--TEST-- +#[\Override]: Properties: invalid promoted property +--FILE-- + +--EXPECTF-- +Fatal error: C::$c has #[\Override] attribute, but no matching parent property exists in %s on line %d diff --git a/Zend/tests/bug34617.phpt b/Zend/tests/bug34617.phpt index a6f3ea8ca7f..736f31d032e 100644 --- a/Zend/tests/bug34617.phpt +++ b/Zend/tests/bug34617.phpt @@ -11,7 +11,6 @@ function boom() $thing = new Thing(); xml_set_object($reader, $thing); die("ok\n"); - xml_parser_free($reader); } boom(); ?> diff --git a/Zend/tests/bug40236.phpt b/Zend/tests/bug40236.phpt index 7ed298c1eed..5fb3fddc573 100644 --- a/Zend/tests/bug40236.phpt +++ b/Zend/tests/bug40236.phpt @@ -8,7 +8,7 @@ if (extension_loaded("readline")) die("skip Test doesn't support readline"); --EXPECT-- Interactive shell (-a) requires the readline extension. diff --git a/Zend/tests/bug41421.phpt b/Zend/tests/bug41421.phpt index 762c32b96df..fdf86da4438 100644 --- a/Zend/tests/bug41421.phpt +++ b/Zend/tests/bug41421.phpt @@ -9,22 +9,19 @@ class wrapper { return true; } function stream_eof() { - throw new exception(); + throw new Exception('cannot eof'); } } stream_wrapper_register("wrap", "wrapper"); $fp = fopen("wrap://...", "r"); -feof($fp); -echo "Done\n"; +try { + feof($fp); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; +} + ?> ---EXPECTF-- -Warning: feof(): wrapper::stream_eof is not implemented! Assuming EOF in %s on line %d - -Fatal error: Uncaught Exception in %s:%d -Stack trace: -#0 [internal function]: wrapper->stream_eof() -#1 %s(%d): feof(Resource id #%d) -#2 {main} - thrown in %s on line %d +--EXPECT-- +Exception: cannot eof diff --git a/Zend/tests/bug55509.phpt b/Zend/tests/bug55509.phpt index b45150a4979..942df09bc0f 100644 --- a/Zend/tests/bug55509.phpt +++ b/Zend/tests/bug55509.phpt @@ -28,7 +28,7 @@ if (PHP_OS == 'Linux') { } } elseif (PHP_OS == 'FreeBSD') { - $lines = explode("\n",`sysctl -a`); + $lines = explode("\n", shell_exec("sysctl -a")); $infos = array(); foreach ($lines as $line) { if (!$line){ diff --git a/Zend/tests/bug64677.phpt b/Zend/tests/bug64677.phpt index c3b168bd83b..4995602e001 100644 --- a/Zend/tests/bug64677.phpt +++ b/Zend/tests/bug64677.phpt @@ -17,5 +17,12 @@ function show_outputa($prepend, $output) { show_outputa('Files: ', `cd .`); // this works as expected ?> ---EXPECT-- +--EXPECTF-- +Deprecated: The backtick (`) operator is deprecated, use shell_exec() instead in %s on line %d + +Deprecated: The backtick (`) operator is deprecated, use shell_exec() instead in %s on line %d + +Deprecated: The backtick (`) operator is deprecated, use shell_exec() instead in %s on line %d + +Deprecated: The backtick (`) operator is deprecated, use shell_exec() instead in %s on line %d Okey diff --git a/Zend/tests/bug67368.phpt b/Zend/tests/bug67368.phpt index f588270f598..50ca00d36d4 100644 --- a/Zend/tests/bug67368.phpt +++ b/Zend/tests/bug67368.phpt @@ -1,7 +1,5 @@ --TEST-- Bug #67368 (Memory leak with immediately dereferenced array in class constant) ---INI-- -report_memleaks=1 --FILE-- ---EXPECT-- -bool(true) -bool(false) -bool(true) -bool(false) diff --git a/Zend/tests/bug81104.phpt b/Zend/tests/bug81104.phpt index 8e7d7e7d738..12c137170fe 100644 --- a/Zend/tests/bug81104.phpt +++ b/Zend/tests/bug81104.phpt @@ -2,7 +2,6 @@ Bug #81104: Warning: "Failed to set memory limit to ... bytes" emitted after exit in debug --INI-- memory_limit=5M -report_memleaks=0 --FILE-- 'BAZ', + 'array' => [1, 2, 3], +]; + +var_dump(clone $x); +var_dump(clone($x)); +var_dump(clone($x, [ 'foo' => $foo, 'bar' => $bar ])); +var_dump(clone($x, $array)); +var_dump(clone($x, [ 'obj' => $x ])); + +var_dump(clone($x, [ + 'abc', + 'def', + new Dummy(), + 'named' => 'value', +])); + +?> +--EXPECTF-- +object(stdClass)#%d (0) { +} +object(stdClass)#%d (0) { +} +object(stdClass)#%d (2) { + ["foo"]=> + string(3) "FOO" + ["bar"]=> + object(Dummy)#%d (0) { + } +} +object(stdClass)#%d (2) { + ["baz"]=> + string(3) "BAZ" + ["array"]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } +} +object(stdClass)#%d (1) { + ["obj"]=> + object(stdClass)#%d (0) { + } +} +object(stdClass)#%d (4) { + ["0"]=> + string(3) "abc" + ["1"]=> + string(3) "def" + ["2"]=> + object(Dummy)#%d (0) { + } + ["named"]=> + string(5) "value" +} diff --git a/Zend/tests/clone/clone_with_002.phpt b/Zend/tests/clone/clone_with_002.phpt new file mode 100644 index 00000000000..8b86e64c76a --- /dev/null +++ b/Zend/tests/clone/clone_with_002.phpt @@ -0,0 +1,114 @@ +--TEST-- +Clone with respects visiblity +--FILE-- + 'updated A', 'b' => 'updated B', 'c' => 'updated C', 'd' => 'updated D' ]); + } +} + +class C extends P { + public function m2() { + return clone($this, [ 'a' => 'updated A', 'b' => 'updated B', 'c' => 'dynamic C' ]); + } + + public function m3() { + return clone($this, [ 'd' => 'inaccessible' ]); + } +} + +class Unrelated { + public function m3(P $p) { + return clone($p, [ 'b' => 'inaccessible' ]); + } +} + +$p = new P(); + +var_dump(clone($p, [ 'a' => 'updated A' ])); +var_dump($p->m1()); + +$c = new C(); +var_dump($c->m1()); +var_dump($c->m2()); +try { + var_dump($c->m3()); +} catch (Error $e) { + echo $e::class, ": ", $e->getMessage(), PHP_EOL; +} + +try { + var_dump(clone($p, [ 'b' => 'inaccessible' ])); +} catch (Error $e) { + echo $e::class, ": ", $e->getMessage(), PHP_EOL; +} + +try { + var_dump(clone($p, [ 'd' => 'inaccessible' ])); +} catch (Error $e) { + echo $e::class, ": ", $e->getMessage(), PHP_EOL; +} + +try { + var_dump((new Unrelated())->m3($p)); +} catch (Error $e) { + echo $e::class, ": ", $e->getMessage(), PHP_EOL; +} + +?> +--EXPECTF-- +object(P)#%d (4) { + ["a"]=> + string(9) "updated A" + ["b":protected]=> + string(7) "default" + ["c":"P":private]=> + string(7) "default" + ["d"]=> + string(7) "default" +} +object(P)#%d (4) { + ["a"]=> + string(9) "updated A" + ["b":protected]=> + string(9) "updated B" + ["c":"P":private]=> + string(9) "updated C" + ["d"]=> + string(9) "updated D" +} +object(C)#%d (4) { + ["a"]=> + string(9) "updated A" + ["b":protected]=> + string(9) "updated B" + ["c":"P":private]=> + string(9) "updated C" + ["d"]=> + string(9) "updated D" +} + +Deprecated: Creation of dynamic property C::$c is deprecated in %s on line %d +object(C)#%d (5) { + ["a"]=> + string(9) "updated A" + ["b":protected]=> + string(9) "updated B" + ["c":"P":private]=> + string(7) "default" + ["d"]=> + string(7) "default" + ["c"]=> + string(9) "dynamic C" +} +Error: Cannot modify private(set) property P::$d from scope C +Error: Cannot access protected property P::$b +Error: Cannot modify private(set) property P::$d from global scope +Error: Cannot access protected property P::$b diff --git a/Zend/tests/clone/clone_with_003.phpt b/Zend/tests/clone/clone_with_003.phpt new file mode 100644 index 00000000000..48fb2b1f6a3 --- /dev/null +++ b/Zend/tests/clone/clone_with_003.phpt @@ -0,0 +1,23 @@ +--TEST-- +Clone with supports property hooks +--FILE-- +hooked = strtoupper($value); + } + } +} + +$c = new Clazz(); + +var_dump(clone($c, [ 'hooked' => 'updated' ])); + +?> +--EXPECTF-- +object(Clazz)#%d (1) { + ["hooked"]=> + string(7) "UPDATED" +} diff --git a/Zend/tests/clone/clone_with_004.phpt b/Zend/tests/clone/clone_with_004.phpt new file mode 100644 index 00000000000..e9985d62bd0 --- /dev/null +++ b/Zend/tests/clone/clone_with_004.phpt @@ -0,0 +1,82 @@ +--TEST-- +Clone with evaluation order +--FILE-- +hooked = strtoupper($value); + } + } + + public string $maxLength { + set { + echo __FUNCTION__, PHP_EOL; + + if (strlen($value) > 5) { + throw new \Exception('Length exceeded'); + } + + $this->maxLength = $value; + } + } + + public string $minLength { + set { + echo __FUNCTION__, PHP_EOL; + + if (strlen($value) < 5) { + throw new \Exception('Length unsufficient'); + } + + $this->minLength = $value; + } + } +} + +$c = new Clazz(); + +var_dump(clone($c, [ 'hooked' => 'updated' ])); +echo PHP_EOL; +var_dump(clone($c, [ 'hooked' => 'updated', 'maxLength' => 'abc', 'minLength' => 'abcdef' ])); +echo PHP_EOL; +var_dump(clone($c, [ 'minLength' => 'abcdef', 'hooked' => 'updated', 'maxLength' => 'abc' ])); + +?> +--EXPECTF-- +$hooked::set +object(Clazz)#%d (1) { + ["hooked"]=> + string(7) "UPDATED" + ["maxLength"]=> + uninitialized(string) + ["minLength"]=> + uninitialized(string) +} + +$hooked::set +$maxLength::set +$minLength::set +object(Clazz)#%d (3) { + ["hooked"]=> + string(7) "UPDATED" + ["maxLength"]=> + string(3) "abc" + ["minLength"]=> + string(6) "abcdef" +} + +$minLength::set +$hooked::set +$maxLength::set +object(Clazz)#%d (3) { + ["hooked"]=> + string(7) "UPDATED" + ["maxLength"]=> + string(3) "abc" + ["minLength"]=> + string(6) "abcdef" +} diff --git a/Zend/tests/clone/clone_with_005.phpt b/Zend/tests/clone/clone_with_005.phpt new file mode 100644 index 00000000000..55ffb2423d7 --- /dev/null +++ b/Zend/tests/clone/clone_with_005.phpt @@ -0,0 +1,64 @@ +--TEST-- +Clone with error handling +--FILE-- +hooked = strtoupper($value); + } + } + + public string $maxLength { + set { + echo __FUNCTION__, PHP_EOL; + + if (strlen($value) > 5) { + throw new \Exception('Length exceeded'); + } + + $this->maxLength = $value; + } + } + + public string $minLength { + set { + echo __FUNCTION__, PHP_EOL; + + if (strlen($value) < 5) { + throw new \Exception('Length insufficient'); + } + + $this->minLength = $value; + } + } +} + +$c = new Clazz(); + +try { + var_dump(clone($c, [ 'hooked' => 'updated', 'maxLength' => 'abcdef', 'minLength' => 'abc' ])); +} catch (Throwable $e) { + echo $e::class, ": ", $e->getMessage(), PHP_EOL; +} + +echo PHP_EOL; + +try { + var_dump(clone($c, [ 'hooked' => 'updated', 'minLength' => 'abc', 'maxLength' => 'abcdef' ])); +} catch (Throwable $e) { + echo $e::class, ": ", $e->getMessage(), PHP_EOL; +} + +?> +--EXPECT-- +$hooked::set +$maxLength::set +Exception: Length exceeded + +$hooked::set +$minLength::set +Exception: Length insufficient diff --git a/Zend/tests/clone/clone_with_006.phpt b/Zend/tests/clone/clone_with_006.phpt new file mode 100644 index 00000000000..7b0b8520b8a --- /dev/null +++ b/Zend/tests/clone/clone_with_006.phpt @@ -0,0 +1,16 @@ +--TEST-- +Clone with error cases +--FILE-- +getMessage(), PHP_EOL; +} + +?> +--EXPECT-- +TypeError: clone(): Argument #2 ($withProperties) must be of type array, int given diff --git a/Zend/tests/clone/clone_with_007.phpt b/Zend/tests/clone/clone_with_007.phpt new file mode 100644 index 00000000000..08cefd7f8cb --- /dev/null +++ b/Zend/tests/clone/clone_with_007.phpt @@ -0,0 +1,29 @@ +--TEST-- +Clone with supports __clone +--FILE-- +foo = 'foo updated in __clone'; + $this->bar = 'bar updated in __clone'; + } +} + +$c = new Clazz('foo', 'bar'); + +var_dump(clone($c, [ 'foo' => 'foo updated in clone-with' ])); + +?> +--EXPECTF-- +object(Clazz)#%d (2) { + ["foo"]=> + string(25) "foo updated in clone-with" + ["bar"]=> + string(22) "bar updated in __clone" +} diff --git a/Zend/tests/clone/clone_with_008.phpt b/Zend/tests/clone/clone_with_008.phpt new file mode 100644 index 00000000000..aa2c639fb7f --- /dev/null +++ b/Zend/tests/clone/clone_with_008.phpt @@ -0,0 +1,40 @@ +--TEST-- +Clone with readonly +--FILE-- +b = '__clone'; + } +} + +$c = new Clazz('default', 'default'); + +var_dump(clone($c, [ 'a' => "with" ])); + +try { + var_dump(clone($c, [ 'b' => "with" ])); +} catch (Throwable $e) { + echo $e::class, ": ", $e->getMessage(), PHP_EOL; +} + +?> +--EXPECTF-- +object(Clazz)#%d (2) { + ["a"]=> + string(4) "with" + ["b"]=> + string(7) "__clone" +} +object(Clazz)#%d (2) { + ["a"]=> + string(7) "default" + ["b"]=> + string(4) "with" +} diff --git a/Zend/tests/clone/clone_with_009.phpt b/Zend/tests/clone/clone_with_009.phpt new file mode 100644 index 00000000000..c6a7d2d18b9 --- /dev/null +++ b/Zend/tests/clone/clone_with_009.phpt @@ -0,0 +1,72 @@ +--TEST-- +Clone with lazy objects +--FILE-- + 2 ]); + + var_dump($reflector->isUninitializedLazyObject($obj)); + var_dump($obj); + var_dump($reflector->isUninitializedLazyObject($clone)); + var_dump($clone); +} + +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + return new C(); +}); + +test('Proxy', $obj); + +?> +--EXPECTF-- +# Ghost: +string(11) "initializer" +bool(false) +object(C)#%d (1) { + ["a"]=> + int(1) +} +bool(false) +object(C)#%d (1) { + ["a"]=> + int(2) +} +# Proxy: +string(11) "initializer" +bool(false) +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (1) { + ["a"]=> + int(1) + } +} +bool(false) +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (1) { + ["a"]=> + int(2) + } +} diff --git a/Zend/tests/clone/clone_with_010.phpt b/Zend/tests/clone/clone_with_010.phpt new file mode 100644 index 00000000000..29ecf714fc4 --- /dev/null +++ b/Zend/tests/clone/clone_with_010.phpt @@ -0,0 +1,21 @@ +--TEST-- +Clone with native classes +--FILE-- + "something" ])); +} catch (Throwable $e) { + echo $e::class, ": ", $e->getMessage(), PHP_EOL; +} + +try { + var_dump(clone(new \Random\Engine\Xoshiro256StarStar(), [ 'with' => "something" ])); +} catch (Throwable $e) { + echo $e::class, ": ", $e->getMessage(), PHP_EOL; +} + +?> +--EXPECT-- +Error: Trying to clone an uncloneable object of class Random\Engine\Secure +Error: Cannot create dynamic property Random\Engine\Xoshiro256StarStar::$with diff --git a/Zend/tests/clone/clone_with_011.phpt b/Zend/tests/clone/clone_with_011.phpt new file mode 100644 index 00000000000..5f8e99bb65f --- /dev/null +++ b/Zend/tests/clone/clone_with_011.phpt @@ -0,0 +1,18 @@ +--TEST-- +Clone with name mangling +--FILE-- + 'updated'])); +} catch (Throwable $e) { + echo $e::class, ": ", $e->getMessage(), PHP_EOL; +} + +?> +--EXPECT-- +Error: Cannot access property starting with "\0" diff --git a/Zend/tests/clone/clone_with_012.phpt b/Zend/tests/clone/clone_with_012.phpt new file mode 100644 index 00000000000..e24f0adad7c --- /dev/null +++ b/Zend/tests/clone/clone_with_012.phpt @@ -0,0 +1,35 @@ +--TEST-- +Clone with property hook updating readonly property +--FILE-- +foo = $value; + $this->bar = 'bar updated in hook'; + } + } + + public public(set) readonly string $bar; +} + +$f = new Clazz(); + +var_dump(clone($f, ['foo' => 'foo updated in clone-with'])); + +try { + var_dump(clone($f, ['foo' => 'foo updated in clone-with', 'bar' => 'bar updated in clone-with'])); +} catch (Throwable $e) { + echo $e::class, ": ", $e->getMessage(), PHP_EOL; +} + +?> +--EXPECTF-- +object(Clazz)#%d (2) { + ["foo"]=> + string(25) "foo updated in clone-with" + ["bar"]=> + string(19) "bar updated in hook" +} +Error: Cannot modify readonly property Clazz::$bar diff --git a/Zend/tests/clone/clone_with_013.phpt b/Zend/tests/clone/clone_with_013.phpt new file mode 100644 index 00000000000..13f24632558 --- /dev/null +++ b/Zend/tests/clone/clone_with_013.phpt @@ -0,0 +1,31 @@ +--TEST-- +Clone with references +--FILE-- + &$ref]; + +try { + var_dump(clone($x, $with)); +} catch (Throwable $e) { + echo $e::class, ": ", $e->getMessage(), PHP_EOL; +} + +unset($ref); + +try { + var_dump(clone($x, $with)); +} catch (Throwable $e) { + echo $e::class, ": ", $e->getMessage(), PHP_EOL; +} + +?> +--EXPECTF-- +Error: Cannot assign by reference when cloning with updated properties +object(stdClass)#%d (1) { + ["x"]=> + string(9) "reference" +} diff --git a/Zend/tests/038.phpt b/Zend/tests/closures/closure_array_key_error.phpt similarity index 100% rename from Zend/tests/038.phpt rename to Zend/tests/closures/closure_array_key_error.phpt diff --git a/Zend/tests/036.phpt b/Zend/tests/closures/closure_array_offset_error.phpt similarity index 100% rename from Zend/tests/036.phpt rename to Zend/tests/closures/closure_array_offset_error.phpt diff --git a/Zend/tests/closures/closure_get_current.phpt b/Zend/tests/closures/closure_get_current.phpt new file mode 100644 index 00000000000..3024ff355b5 --- /dev/null +++ b/Zend/tests/closures/closure_get_current.phpt @@ -0,0 +1,64 @@ +--TEST-- +Closure::getCurrent() +--FILE-- +getMessage(), "\n"; +} + +function foo() { + var_dump(Closure::getCurrent()); +} + +try { + foo(...)(); +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} + +?> +--EXPECT-- +int(1) +int(1) +int(2) +int(2) +int(3) +int(3) +int(4) +int(4) +int(5) +int(5) +int(6) +int(6) +int(7) +int(7) +int(8) +int(8) +int(9) +int(9) +int(10) +int(10) +int(11) +Current function is not a closure +Current function is not a closure diff --git a/Zend/tests/037.phpt b/Zend/tests/closures/closure_static_property_error.phpt similarity index 100% rename from Zend/tests/037.phpt rename to Zend/tests/closures/closure_static_property_error.phpt diff --git a/Zend/tests/constants/gh18850.inc b/Zend/tests/constants/gh18850.inc new file mode 100644 index 00000000000..08099278ea3 --- /dev/null +++ b/Zend/tests/constants/gh18850.inc @@ -0,0 +1,5 @@ + +--EXPECT-- +int(62) +int(62) diff --git a/Zend/tests/debug_info/debug_info.phpt b/Zend/tests/debug_info/debug_info.phpt index 6f559eb40b7..bff5876777b 100644 --- a/Zend/tests/debug_info/debug_info.phpt +++ b/Zend/tests/debug_info/debug_info.phpt @@ -36,5 +36,7 @@ object(Foo)#%d (3) { ["c":"Foo":private]=> int(3) } + +Deprecated: Returning null from Bar::__debugInfo() is deprecated, return an empty array instead in %s on line %d object(Bar)#%d (0) { } diff --git a/Zend/tests/debug_info/recursion_return_null.phpt b/Zend/tests/debug_info/recursion_return_null.phpt new file mode 100644 index 00000000000..b6ca9c824cb --- /dev/null +++ b/Zend/tests/debug_info/recursion_return_null.phpt @@ -0,0 +1,31 @@ +--TEST-- +Testing __debugInfo() magic method +--FILE-- + +--EXPECTF-- +in handler + +Deprecated: Returning null from Foo::__debugInfo() is deprecated, return an empty array instead in %s on line %d +object(Foo)#3 (0) { +} +object(Foo)#2 (0) { +} diff --git a/Zend/tests/025.phpt b/Zend/tests/dynamic_call/dynamic_method_calls.phpt similarity index 100% rename from Zend/tests/025.phpt rename to Zend/tests/dynamic_call/dynamic_method_calls.phpt diff --git a/Zend/tests/027.phpt b/Zend/tests/dynamic_call/variable_variables_curly_syntax.phpt similarity index 100% rename from Zend/tests/027.phpt rename to Zend/tests/dynamic_call/variable_variables_curly_syntax.phpt diff --git a/Zend/tests/023.phpt b/Zend/tests/dynamic_call/variable_variables_function_names.phpt similarity index 100% rename from Zend/tests/023.phpt rename to Zend/tests/dynamic_call/variable_variables_function_names.phpt diff --git a/Zend/tests/enum/spl-object-storage.phpt b/Zend/tests/enum/spl-object-storage.phpt index 7c72299c348..10da018b842 100644 --- a/Zend/tests/enum/spl-object-storage.phpt +++ b/Zend/tests/enum/spl-object-storage.phpt @@ -16,8 +16,8 @@ $storage[Foo::Baz] = 'Baz'; var_dump($storage[Foo::Bar]); var_dump($storage[Foo::Baz]); -var_dump($storage->contains(Foo::Bar)); -var_dump($storage->contains(Foo::Qux)); +var_dump($storage->offsetExists(Foo::Bar)); +var_dump($storage->offsetExists(Foo::Qux)); $serialized = serialize($storage); var_dump($serialized); diff --git a/Zend/tests/exceptions/bug26698.phpt b/Zend/tests/exceptions/bug26698.phpt index 834e0b77c24..8155f209059 100644 --- a/Zend/tests/exceptions/bug26698.phpt +++ b/Zend/tests/exceptions/bug26698.phpt @@ -3,8 +3,6 @@ Bug #26698 (Thrown exceptions while evaluating argument to pass as parameter cra --FILE-- int(1) } -Exception: Too few arguments to function test2(), 0 passed in %s003.php on line %d and exactly 1 expected +Exception: Too few arguments to function test2(), 0 passed in %s on line %d and exactly 1 expected array(2) { [0]=> int(1) @@ -68,7 +68,7 @@ array(2) { } array(0) { } -Exception: Too few arguments to function test3(), 1 passed in %s003.php on line %d and exactly 2 expected +Exception: Too few arguments to function test3(), 1 passed in %s on line %d and exactly 2 expected array(2) { [0]=> int(1) diff --git a/Zend/tests/001.phpt b/Zend/tests/func_num_args_basic.phpt similarity index 100% rename from Zend/tests/001.phpt rename to Zend/tests/func_num_args_basic.phpt diff --git a/Zend/tests/028.phpt b/Zend/tests/function_call_array_item.phpt similarity index 100% rename from Zend/tests/028.phpt rename to Zend/tests/function_call_array_item.phpt diff --git a/Zend/tests/gc/gc_046.phpt b/Zend/tests/gc/gc_046.phpt index d5024737365..8d484385352 100644 --- a/Zend/tests/gc/gc_046.phpt +++ b/Zend/tests/gc/gc_046.phpt @@ -20,5 +20,6 @@ $action->filter(); $action->filter(); ?> DONE ---EXPECT-- +--EXPECTF-- +Deprecated: ArrayIterator::__construct(): Using an object as a backing array for ArrayIterator is deprecated, as it allows violating class constraints and invariants in %s on line %d DONE diff --git a/Zend/tests/009.phpt b/Zend/tests/get_class_basic.phpt similarity index 100% rename from Zend/tests/009.phpt rename to Zend/tests/get_class_basic.phpt diff --git a/Zend/tests/get_included_files_basic.inc b/Zend/tests/get_included_files_basic.inc new file mode 100644 index 00000000000..406acaee6e4 --- /dev/null +++ b/Zend/tests/get_included_files_basic.inc @@ -0,0 +1,3 @@ + diff --git a/Zend/tests/014.phpt b/Zend/tests/get_included_files_basic.phpt similarity index 74% rename from Zend/tests/014.phpt rename to Zend/tests/get_included_files_basic.phpt index c02fee93856..be595a59262 100644 --- a/Zend/tests/014.phpt +++ b/Zend/tests/get_included_files_basic.phpt @@ -5,13 +5,13 @@ get_included_files() tests var_dump(get_included_files()); -include(__DIR__."/014.inc"); +include(__DIR__."/get_included_files_basic.inc"); var_dump(get_included_files()); -include_once(__DIR__."/014.inc"); +include_once(__DIR__."/get_included_files_basic.inc"); var_dump(get_included_files()); -include(__DIR__."/014.inc"); +include(__DIR__."/get_included_files_basic.inc"); var_dump(get_included_files()); echo "Done\n"; diff --git a/Zend/tests/010.phpt b/Zend/tests/get_parent_class_basic.phpt similarity index 100% rename from Zend/tests/010.phpt rename to Zend/tests/get_parent_class_basic.phpt diff --git a/Zend/tests/gh18581.phpt b/Zend/tests/gh18581.phpt new file mode 100644 index 00000000000..cc5c0fff02e --- /dev/null +++ b/Zend/tests/gh18581.phpt @@ -0,0 +1,32 @@ +--TEST-- +GH-18581: Coerce numeric string keys from iterators when argument unpacking +--FILE-- + 'first'; + yield '101' => 'second'; + yield '102' => 'third'; + yield 'named' => 'fourth'; +} + +function test($x = null, $y = null, ...$z) { + var_dump($x, $y, $z); + var_dump($z[0]); + var_dump($z['named']); +} + +test(...g()); + +?> +--EXPECT-- +string(5) "first" +string(6) "second" +array(2) { + [0]=> + string(5) "third" + ["named"]=> + string(6) "fourth" +} +string(5) "third" +string(6) "fourth" diff --git a/Zend/tests/gh18736.phpt b/Zend/tests/gh18736.phpt new file mode 100644 index 00000000000..f397ee39a31 --- /dev/null +++ b/Zend/tests/gh18736.phpt @@ -0,0 +1,24 @@ +--TEST-- +GH-18736: Circumvented type check with return by ref + finally +--FILE-- +getMessage(), "\n"; +} + +?> +--EXPECT-- +test(): Return value must be of type int, string returned diff --git a/Zend/tests/gh19044.phpt b/Zend/tests/gh19044.phpt new file mode 100644 index 00000000000..3477dd3c8b0 --- /dev/null +++ b/Zend/tests/gh19044.phpt @@ -0,0 +1,26 @@ +--TEST-- +GH-19044: Protected properties must be scoped according to their prototype +--FILE-- +foo; } +} + +var_dump(C2::foo(new C2)); +var_dump(C2::foo(new C1)); + +?> +--EXPECT-- +int(2) +int(1) diff --git a/Zend/tests/gh19053.phpt b/Zend/tests/gh19053.phpt new file mode 100644 index 00000000000..7c82f1bc5f4 --- /dev/null +++ b/Zend/tests/gh19053.phpt @@ -0,0 +1,26 @@ +--TEST-- +GH-19053: Incorrect properties_info_table for abstract properties +--FILE-- + 2; } +} + +$c = new C; +var_dump($c); + +?> +--EXPECTF-- +object(C)#%d (0) { + ["foo"]=> + uninitialized(mixed) +} diff --git a/Zend/tests/gh19280.phpt b/Zend/tests/gh19280.phpt new file mode 100644 index 00000000000..d73fc91b623 --- /dev/null +++ b/Zend/tests/gh19280.phpt @@ -0,0 +1,81 @@ +--TEST-- +GH-19280: Stale nInternalPosition on rehashing +--FILE-- += 0; $i--) { + $a[$i] = $i; + } + for ($i = 0; $i <= 47; $i++) { + next($a); + } + for ($i = 48; $i >= 2; $i--) { + unset($a[$i]); + } + var_dump(key($a)); + $a[64] = 64; + var_dump(key($a)); +} + +rehash_packed(); +rehash_packed_iterated(); +rehash_string(); +rehash_int(); + +?> +--EXPECT-- +int(62) +int(62) +int(62) +int(62) +string(32) "44f683a84163b3523afe57c2e008bc8c" +string(32) "44f683a84163b3523afe57c2e008bc8c" +int(1) +int(1) diff --git a/Zend/tests/gh19304.phpt b/Zend/tests/gh19304.phpt new file mode 100644 index 00000000000..c77fc2d6fac --- /dev/null +++ b/Zend/tests/gh19304.phpt @@ -0,0 +1,18 @@ +--TEST-- +GH-19304: Incorrect anonymous class type name assertion +--FILE-- +v = 0; +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} + +?> +--EXPECT-- +Cannot assign int to property class@anonymous::$v of type class@anonymous diff --git a/Zend/tests/gh19305-001.phpt b/Zend/tests/gh19305-001.phpt new file mode 100644 index 00000000000..4c9ee37473e --- /dev/null +++ b/Zend/tests/gh19305-001.phpt @@ -0,0 +1,27 @@ +--TEST-- +GH-19305 001: Operands may be released during comparison +--FILE-- + 'test', + 'bar' => 2, +]; +$b = (object)[ + 'foo' => new class { + public function __toString() { + global $a, $b; + $a = $b = null; + return ''; + } + }, + 'bar' => 2, +]; + +// Comparison of $a->foo and $b->foo calls __toString(), which releases +// both $a and $b. +var_dump($a > $b); + +?> +--EXPECT-- +bool(true) diff --git a/Zend/tests/gh19305-002.phpt b/Zend/tests/gh19305-002.phpt new file mode 100644 index 00000000000..79015619131 --- /dev/null +++ b/Zend/tests/gh19305-002.phpt @@ -0,0 +1,27 @@ +--TEST-- +GH-19305 002: Operands may be released during comparison +--FILE-- + 'test', + 'bar' => 2, +]; +$b = [ + 'foo' => new class { + public function __toString() { + global $a, $b; + $a = $b = null; + return ''; + } + }, + 'bar' => 2, +]; + +// Comparison of $a['foo'] and $b['foo'] calls __toString(), which releases +// both $a and $b. +var_dump($a > $b); + +?> +--EXPECT-- +bool(true) diff --git a/Zend/tests/gh19305-003.phpt b/Zend/tests/gh19305-003.phpt new file mode 100644 index 00000000000..7b071156ef8 --- /dev/null +++ b/Zend/tests/gh19305-003.phpt @@ -0,0 +1,28 @@ +--TEST-- +GH-19305 003: Operands may be released during comparison +--SKIPIF-- + +--FILE-- +newLazyProxy(function () { return new C; }); + +// Comparison calls initializers, which releases $o +var_dump($o > +$r->newLazyGhost(function () { + global $o; + $o = null; +})); + +?> +--EXPECT-- +bool(false) diff --git a/Zend/tests/gh19306.phpt b/Zend/tests/gh19306.phpt new file mode 100644 index 00000000000..e19735d94c8 --- /dev/null +++ b/Zend/tests/gh19306.phpt @@ -0,0 +1,40 @@ +--TEST-- +GH-19306: Generator suspended in yield from may be resumed +--FILE-- +next(); + echo "Fiber return\n"; +}); +$fiber->start(); +echo "Fiber suspended\n"; +try { + $a->next(); +} catch (Throwable $t) { + echo $t->getMessage(), "\n"; +} +echo "Destroying fiber\n"; +$fiber = null; +echo "Shutdown\n"; +?> +--EXPECT-- +Fiber start +Fiber suspended +Cannot resume an already running generator +Destroying fiber +Shutdown diff --git a/Zend/tests/gh19326.phpt b/Zend/tests/gh19326.phpt new file mode 100644 index 00000000000..335fdd382ea --- /dev/null +++ b/Zend/tests/gh19326.phpt @@ -0,0 +1,36 @@ +--TEST-- +GH-19326: Calling Generator::throw() on a running generator with a non-Generator delegate crashes +--FILE-- +rewind(); + +$fiber = new Fiber(function () use ($b) { + $b->next(); +}); + +$fiber->start(); + +try { + $b->throw(new Exception('test')); +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} + +$fiber->resume(); + +?> +--EXPECT-- +Cannot resume an already running generator diff --git a/Zend/tests/inheritance/deprecation_to_exception_during_inheritance.phpt b/Zend/tests/inheritance/deprecation_to_exception_during_inheritance.phpt index 6e7e81cd295..4bdf4b5d1b9 100644 --- a/Zend/tests/inheritance/deprecation_to_exception_during_inheritance.phpt +++ b/Zend/tests/inheritance/deprecation_to_exception_during_inheritance.phpt @@ -1,5 +1,5 @@ --TEST-- -Deprecation promoted to exception should result in fatal error during inheritance +Deprecation promoted to exception during inheritance --SKIPIF-- --EXPECTF-- -Fatal error: During inheritance of DateTime: Uncaught Exception: 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 in %s:%d +Fatal error: Uncaught Exception: 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 in %s:%d Stack trace: #0 %s(%d): {closure:%s:%d}(8192, 'Return type of ...', '%s', 8) -#1 {main} in %s on line %d +#1 {main} + thrown in %s on line %d diff --git a/Zend/tests/inheritance/deprecation_to_exception_during_inheritance_can_be_caught.phpt b/Zend/tests/inheritance/deprecation_to_exception_during_inheritance_can_be_caught.phpt new file mode 100644 index 00000000000..7a59cca70bd --- /dev/null +++ b/Zend/tests/inheritance/deprecation_to_exception_during_inheritance_can_be_caught.phpt @@ -0,0 +1,35 @@ +--TEST-- +Deprecation promoted to exception during inheritance +--SKIPIF-- + +--FILE-- +getMessage()); +} + +var_dump(new C()); + +?> +--EXPECTF-- +Exception: Return type of C::getTimezone() should either be compatible with DateTime::getTimezone(): DateTimeZone|false, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice +object(C)#%d (3) { + ["date"]=> + string(%d) "%s" + ["timezone_type"]=> + int(3) + ["timezone"]=> + string(3) "UTC" +} diff --git a/Zend/tests/inheritance/gh15907.phpt b/Zend/tests/inheritance/gh15907.phpt index 8d6dada36ad..c92e40a4ba3 100644 --- a/Zend/tests/inheritance/gh15907.phpt +++ b/Zend/tests/inheritance/gh15907.phpt @@ -14,5 +14,8 @@ class C implements Serializable { ?> --EXPECTF-- -Fatal error: During inheritance of C, while implementing Serializable: Uncaught Exception: C implements the Serializable interface, which is deprecated. Implement __serialize() and __unserialize() instead (or in addition, if support for old PHP versions is necessary) in %s:%d -%a +Fatal error: Uncaught Exception: C implements the Serializable interface, which is deprecated. Implement __serialize() and __unserialize() instead (or in addition, if support for old PHP versions is necessary) in %s:%d +Stack trace: +#0 %s(%d): {closure:%s:%d}(8192, 'C implements th...', '%s', 7) +#1 {main} + thrown in %s on line %d diff --git a/Zend/tests/013.phpt b/Zend/tests/interface_exists_basic.phpt similarity index 100% rename from Zend/tests/013.phpt rename to Zend/tests/interface_exists_basic.phpt diff --git a/Zend/tests/016.phpt b/Zend/tests/isset_non_object.phpt similarity index 100% rename from Zend/tests/016.phpt rename to Zend/tests/isset_non_object.phpt diff --git a/Zend/tests/lazy_objects/skipLazyInitialization.phpt b/Zend/tests/lazy_objects/skipLazyInitialization.phpt index d4d564d9c65..4fc47b13db6 100644 --- a/Zend/tests/lazy_objects/skipLazyInitialization.phpt +++ b/Zend/tests/lazy_objects/skipLazyInitialization.phpt @@ -227,7 +227,7 @@ getValue(): NULL setRawValueWithoutLazyInitialization(): getValue(): string(5) "value" -## Property [ public $hooked = NULL ] +## Property [ public $hooked = NULL { get; set; } ] skipInitializerForProperty(): getValue(): NULL @@ -235,7 +235,7 @@ getValue(): NULL setRawValueWithoutLazyInitialization(): getValue(): string(5) "value" -## Property [ public $virtual ] +## Property [ public virtual $virtual { get; set; } ] skipInitializerForProperty(): ReflectionException: Can not use skipLazyInitialization on virtual property A::$virtual @@ -324,7 +324,7 @@ getValue(): NULL setRawValueWithoutLazyInitialization(): getValue(): string(5) "value" -## Property [ public $hooked = NULL ] +## Property [ public $hooked = NULL { get; set; } ] skipInitializerForProperty(): getValue(): NULL @@ -332,7 +332,7 @@ getValue(): NULL setRawValueWithoutLazyInitialization(): getValue(): string(5) "value" -## Property [ public $virtual ] +## Property [ public virtual $virtual { get; set; } ] skipInitializerForProperty(): ReflectionException: Can not use skipLazyInitialization on virtual property A::$virtual diff --git a/Zend/tests/oct_overflow.phpt b/Zend/tests/oct_overflow.phpt index 512a6abf664..b8ce3f40fde 100644 --- a/Zend/tests/oct_overflow.phpt +++ b/Zend/tests/oct_overflow.phpt @@ -5,7 +5,7 @@ precision=14 --FILE-- getMessage(), "\n"; +} + +?> +--EXPECT-- +Foo::__toString(): Return value must be of type string, none returned diff --git a/Zend/tests/pipe_operator_reference_context.phpt b/Zend/tests/pipe_operator_reference_context.phpt new file mode 100644 index 00000000000..7d7572e2b2e --- /dev/null +++ b/Zend/tests/pipe_operator_reference_context.phpt @@ -0,0 +1,26 @@ +--TEST-- +Fix GH-19476: Pipe operator with function returning by reference +--FILE-- + get_ref(...); +} + +$ref = &test_pipe_ref(); +echo "Before: " . $ref . "\n"; +$ref = "changed"; +echo "After: " . test_pipe_ref() . "\n"; + +?> +--EXPECT-- +Before: original input +After: changed input diff --git a/Zend/tests/011.phpt b/Zend/tests/property_exists_basic.phpt similarity index 100% rename from Zend/tests/011.phpt rename to Zend/tests/property_exists_basic.phpt diff --git a/Zend/tests/property_hooks/cpp.phpt b/Zend/tests/property_hooks/cpp.phpt index 082c182467b..1f893d853b8 100644 --- a/Zend/tests/property_hooks/cpp.phpt +++ b/Zend/tests/property_hooks/cpp.phpt @@ -24,11 +24,13 @@ var_dump($r->hasDefaultValue()); var_dump($r->getDefaultValue()); ?> ---EXPECT-- +--EXPECTF-- Pre-test Setting Constructor Getting Setting bool(false) + +Deprecated: ReflectionProperty::getDefaultValue() for a property without a default value is deprecated, use ReflectionProperty::hasDefaultValue() to check if the default value exists in %s on line %d NULL diff --git a/Zend/tests/property_hooks/gh19044-1.phpt b/Zend/tests/property_hooks/gh19044-1.phpt new file mode 100644 index 00000000000..133727c73de --- /dev/null +++ b/Zend/tests/property_hooks/gh19044-1.phpt @@ -0,0 +1,26 @@ +--TEST-- +GH-19044: Protected properties must be scoped according to their prototype (common ancestor has a protected setter) +--FILE-- + 1; set {} } +} + +class GrandC1 extends C1 { + public protected(set) mixed $foo { get => 2; set {} } +} + +class C2 extends C1 { + static function foo($c) { return $c->foo += 1; } +} + +var_dump(C2::foo(new GrandC1)); + +?> +--EXPECT-- +int(3) diff --git a/Zend/tests/property_hooks/gh19044-2.phpt b/Zend/tests/property_hooks/gh19044-2.phpt new file mode 100644 index 00000000000..ed73c60dc5a --- /dev/null +++ b/Zend/tests/property_hooks/gh19044-2.phpt @@ -0,0 +1,26 @@ +--TEST-- +GH-19044: Protected properties must be scoped according to their prototype (common ancestor does not have a setter) +--FILE-- + 1; } +} + +class GrandC1 extends C1 { + public protected(set) mixed $foo { get => 2; set {} } +} + +class C2 extends C1 { + static function foo($c) { return $c->foo += 1; } +} + +var_dump(C2::foo(new GrandC1)); + +?> +--EXPECT-- +int(3) diff --git a/Zend/tests/property_hooks/gh19044-3.phpt b/Zend/tests/property_hooks/gh19044-3.phpt new file mode 100644 index 00000000000..3d4f6789a5a --- /dev/null +++ b/Zend/tests/property_hooks/gh19044-3.phpt @@ -0,0 +1,24 @@ +--TEST-- +GH-19044: Protected properties must be scoped according to their prototype (abstract parent defining visibility only takes precedence) +--FILE-- + 2; set {} } +} + +class C2 extends P { + public mixed $foo = 1; + + static function foo($c) { return $c->foo += 1; } +} + +var_dump(C2::foo(new C1)); + +?> +--EXPECT-- +int(3) diff --git a/Zend/tests/property_hooks/gh19044-4.phpt b/Zend/tests/property_hooks/gh19044-4.phpt new file mode 100644 index 00000000000..e1abf473908 --- /dev/null +++ b/Zend/tests/property_hooks/gh19044-4.phpt @@ -0,0 +1,28 @@ +--TEST-- +GH-19044: Protected properties must be scoped according to their prototype (abstract parent sets protected(set) with not having grandparent a setter - both inherit from parent) +--FILE-- + 2; set {} } +} + +class C2 extends P { + public mixed $foo = 1; + + static function foo($c) { return $c->foo += 1; } +} + +var_dump(C2::foo(new C1)); + +?> +--EXPECT-- +int(3) diff --git a/Zend/tests/property_hooks/gh19044-5.phpt b/Zend/tests/property_hooks/gh19044-5.phpt new file mode 100644 index 00000000000..773682961ab --- /dev/null +++ b/Zend/tests/property_hooks/gh19044-5.phpt @@ -0,0 +1,28 @@ +--TEST-- +GH-19044: Protected properties must be scoped according to their prototype (abstract parent sets protected(set) with not having grandparent a setter - one inherits from grandparent) +--FILE-- + 2; set {} } +} + +class C2 extends GP { + public mixed $foo = 1; + + static function foo($c) { return $c->foo += 1; } +} + +var_dump(C2::foo(new C1)); + +?> +--EXPECT-- +int(3) diff --git a/Zend/tests/property_hooks/gh19044-6.phpt b/Zend/tests/property_hooks/gh19044-6.phpt new file mode 100644 index 00000000000..43332698fe9 --- /dev/null +++ b/Zend/tests/property_hooks/gh19044-6.phpt @@ -0,0 +1,28 @@ +--TEST-- +GH-19044: Protected properties must be scoped according to their prototype (abstract parent has implicit set hook) +--FILE-- + $this->foo; } +} + +class C1 extends P { + public protected(set) mixed $foo = 1; +} + +class C2 extends P { + public protected(set) mixed $foo; + + static function foo($c) { return $c->foo += 1; } +} + +var_dump(C2::foo(new C1)); + +?> +--EXPECT-- +int(2) diff --git a/Zend/tests/property_hooks/gh19044-8.phpt b/Zend/tests/property_hooks/gh19044-8.phpt new file mode 100644 index 00000000000..2fa62e4619f --- /dev/null +++ b/Zend/tests/property_hooks/gh19044-8.phpt @@ -0,0 +1,26 @@ +--TEST-- +GH-19044: Protected properties must be scoped according to their prototype (hooks variation) +--FILE-- +foo; } +} + +var_dump(C2::foo(new C2)); +var_dump(C2::foo(new C1)); + +?> +--EXPECT-- +int(2) +int(1) diff --git a/Zend/tests/readonly_classes/gh10377_1.phpt b/Zend/tests/readonly_classes/gh10377_1.phpt index ac421cb8a51..fba1605ff08 100644 --- a/Zend/tests/readonly_classes/gh10377_1.phpt +++ b/Zend/tests/readonly_classes/gh10377_1.phpt @@ -12,4 +12,4 @@ $readonly_anon = new #[AllowDynamicProperties] readonly class { ?> --EXPECTF-- -Fatal error: Cannot apply #[AllowDynamicProperties] to readonly class class@anonymous in %s on line %d +Fatal error: Cannot apply #[\AllowDynamicProperties] to readonly class class@anonymous in %s on line %d diff --git a/Zend/tests/readonly_classes/readonly_class_dynamic_property_attribute.phpt b/Zend/tests/readonly_classes/readonly_class_dynamic_property_attribute.phpt index ace50c572ac..fab37dccfbf 100644 --- a/Zend/tests/readonly_classes/readonly_class_dynamic_property_attribute.phpt +++ b/Zend/tests/readonly_classes/readonly_class_dynamic_property_attribute.phpt @@ -10,4 +10,4 @@ readonly class Foo ?> --EXPECTF-- -Fatal error: Cannot apply #[AllowDynamicProperties] to readonly class Foo in %s on line %d +Fatal error: Cannot apply #[\AllowDynamicProperties] to readonly class Foo in %s on line %d diff --git a/Zend/tests/035.phpt b/Zend/tests/static_global_scope.phpt similarity index 100% rename from Zend/tests/035.phpt rename to Zend/tests/static_global_scope.phpt diff --git a/Zend/tests/005.phpt b/Zend/tests/strcasecmp_basic.phpt similarity index 100% rename from Zend/tests/005.phpt rename to Zend/tests/strcasecmp_basic.phpt diff --git a/Zend/tests/006.phpt b/Zend/tests/strncasecmp_basic.phpt similarity index 100% rename from Zend/tests/006.phpt rename to Zend/tests/strncasecmp_basic.phpt diff --git a/Zend/tests/004.phpt b/Zend/tests/strncmp_basic.phpt similarity index 100% rename from Zend/tests/004.phpt rename to Zend/tests/strncmp_basic.phpt diff --git a/Zend/tests/021.phpt b/Zend/tests/ternary_operator_basic.phpt similarity index 100% rename from Zend/tests/021.phpt rename to Zend/tests/ternary_operator_basic.phpt diff --git a/Zend/tests/015.phpt b/Zend/tests/trigger_error_basic.phpt similarity index 100% rename from Zend/tests/015.phpt rename to Zend/tests/trigger_error_basic.phpt diff --git a/Zend/tests/type_casts/cast_to_double.phpt b/Zend/tests/type_casts/cast_to_double.phpt index 2972fbbe802..69a625b09de 100644 --- a/Zend/tests/type_casts/cast_to_double.phpt +++ b/Zend/tests/type_casts/cast_to_double.phpt @@ -1,5 +1,5 @@ --TEST-- -casting different variables to double +casting different variables to float --INI-- precision=14 --FILE-- @@ -32,7 +32,7 @@ $vars = array( ); foreach ($vars as $var) { - $tmp = (double)$var; + $tmp = (float)$var; var_dump($tmp); } diff --git a/Zend/tests/type_casts/non_canonical_binary_cast.phpt b/Zend/tests/type_casts/non_canonical_binary_cast.phpt new file mode 100644 index 00000000000..fc7aa59ac90 --- /dev/null +++ b/Zend/tests/type_casts/non_canonical_binary_cast.phpt @@ -0,0 +1,11 @@ +--TEST-- +Non canonical (binary) cast +--FILE-- + +--EXPECTF-- +Deprecated: Non-canonical cast (binary) is deprecated, use the (string) cast instead in %s on line %d +string(2) "42" diff --git a/Zend/tests/type_casts/non_canonical_boolean_cast.phpt b/Zend/tests/type_casts/non_canonical_boolean_cast.phpt new file mode 100644 index 00000000000..e0db0eec475 --- /dev/null +++ b/Zend/tests/type_casts/non_canonical_boolean_cast.phpt @@ -0,0 +1,11 @@ +--TEST-- +Non canonical (boolean) cast +--FILE-- + +--EXPECTF-- +Deprecated: Non-canonical cast (boolean) is deprecated, use the (bool) cast instead in %s on line %d +bool(true) diff --git a/Zend/tests/type_casts/non_canonical_double_cast.phpt b/Zend/tests/type_casts/non_canonical_double_cast.phpt new file mode 100644 index 00000000000..91769a206a4 --- /dev/null +++ b/Zend/tests/type_casts/non_canonical_double_cast.phpt @@ -0,0 +1,11 @@ +--TEST-- +Non canonical (double) cast +--FILE-- + +--EXPECTF-- +Deprecated: Non-canonical cast (double) is deprecated, use the (float) cast instead in %s on line %d +float(42) diff --git a/Zend/tests/type_casts/non_canonical_integer_cast.phpt b/Zend/tests/type_casts/non_canonical_integer_cast.phpt new file mode 100644 index 00000000000..4f428ff9d53 --- /dev/null +++ b/Zend/tests/type_casts/non_canonical_integer_cast.phpt @@ -0,0 +1,11 @@ +--TEST-- +Non canonical (integer) cast +--FILE-- + +--EXPECTF-- +Deprecated: Non-canonical cast (integer) is deprecated, use the (int) cast instead in %s on line %d +int(42) diff --git a/Zend/tests/type_declarations/typed_properties_113.phpt b/Zend/tests/type_declarations/typed_properties_113.phpt index cb5c0f92764..0aecc76f758 100644 --- a/Zend/tests/type_declarations/typed_properties_113.phpt +++ b/Zend/tests/type_declarations/typed_properties_113.phpt @@ -19,7 +19,8 @@ foreach ($obj as $k => &$v) { var_dump($obj); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: ArrayIterator::__construct(): Using an object as a backing array for ArrayIterator is deprecated, as it allows violating class constraints and invariants in %s on line %d object(A)#1 (1) { ["foo"]=> &string(2) "42" diff --git a/Zend/tests/type_declarations/typed_properties_114.phpt b/Zend/tests/type_declarations/typed_properties_114.phpt index e771f4c1c1f..5f3093dd330 100644 --- a/Zend/tests/type_declarations/typed_properties_114.phpt +++ b/Zend/tests/type_declarations/typed_properties_114.phpt @@ -30,8 +30,11 @@ foreach ($obj as $k => &$v) { var_dump($obj); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: ArrayIterator::__construct(): Using an object as a backing array for ArrayIterator is deprecated, as it allows violating class constraints and invariants in %s on line %d Cannot assign array to reference held by property A::$foo of type string + +Deprecated: ArrayIterator::__construct(): Using an object as a backing array for ArrayIterator is deprecated, as it allows violating class constraints and invariants in %s on line %d Cannot assign array to reference held by property A::$foo of type string object(A)#1 (1) { ["foo"]=> diff --git a/Zend/tests/type_declarations/typed_properties_115.phpt b/Zend/tests/type_declarations/typed_properties_115.phpt index eb96b3ee886..6347ee0c35d 100644 --- a/Zend/tests/type_declarations/typed_properties_115.phpt +++ b/Zend/tests/type_declarations/typed_properties_115.phpt @@ -22,7 +22,8 @@ try { var_dump($obj); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: ArrayIterator::__construct(): Using an object as a backing array for ArrayIterator is deprecated, as it allows violating class constraints and invariants in %s on line %d Cannot acquire reference to readonly property A::$foo object(A)#1 (1) { ["foo"]=> diff --git a/Zend/tests/033.phpt b/Zend/tests/undefined_multidimensional_array.phpt similarity index 100% rename from Zend/tests/033.phpt rename to Zend/tests/undefined_multidimensional_array.phpt diff --git a/Zend/tests/024.phpt b/Zend/tests/undefined_variables_operations.phpt similarity index 100% rename from Zend/tests/024.phpt rename to Zend/tests/undefined_variables_operations.phpt diff --git a/Zend/tests/019.phpt b/Zend/tests/unset_empty_isset_comprehensive.phpt similarity index 100% rename from Zend/tests/019.phpt rename to Zend/tests/unset_empty_isset_comprehensive.phpt diff --git a/Zend/zend.c b/Zend/zend.c index 2d8a0f455f8..2f5a21ef240 100644 --- a/Zend/zend.c +++ b/Zend/zend.c @@ -1452,6 +1452,29 @@ ZEND_API ZEND_COLD void zend_error_zstr_at( return; } + /* Emit any delayed error before handling fatal error */ + if ((type & E_FATAL_ERRORS) && !(type & E_DONT_BAIL) && EG(num_errors)) { + uint32_t num_errors = EG(num_errors); + zend_error_info **errors = EG(errors); + EG(num_errors) = 0; + EG(errors) = NULL; + + bool orig_record_errors = EG(record_errors); + EG(record_errors) = false; + + /* Disable user error handler before emitting delayed errors, as + * it's unsafe to execute user code after a fatal error. */ + int orig_user_error_handler_error_reporting = EG(user_error_handler_error_reporting); + EG(user_error_handler_error_reporting) = 0; + + zend_emit_recorded_errors_ex(num_errors, errors); + + EG(user_error_handler_error_reporting) = orig_user_error_handler_error_reporting; + EG(record_errors) = orig_record_errors; + EG(num_errors) = num_errors; + EG(errors) = errors; + } + if (EG(record_errors)) { zend_error_info *info = emalloc(sizeof(zend_error_info)); info->type = type; @@ -1464,6 +1487,11 @@ ZEND_API ZEND_COLD void zend_error_zstr_at( EG(num_errors)++; EG(errors) = erealloc(EG(errors), sizeof(zend_error_info*) * EG(num_errors)); EG(errors)[EG(num_errors)-1] = info; + + /* Do not process non-fatal recorded error */ + if (!(type & E_FATAL_ERRORS) || (type & E_DONT_BAIL)) { + return; + } } // Always clear the last backtrace. @@ -1752,13 +1780,18 @@ ZEND_API void zend_begin_record_errors(void) EG(errors) = NULL; } +ZEND_API void zend_emit_recorded_errors_ex(uint32_t num_errors, zend_error_info **errors) +{ + for (uint32_t i = 0; i < num_errors; i++) { + zend_error_info *error = errors[i]; + zend_error_zstr_at(error->type, error->filename, error->lineno, error->message); + } +} + ZEND_API void zend_emit_recorded_errors(void) { EG(record_errors) = false; - for (uint32_t i = 0; i < EG(num_errors); i++) { - zend_error_info *error = EG(errors)[i]; - zend_error_zstr_at(error->type, error->filename, error->lineno, error->message); - } + zend_emit_recorded_errors_ex(EG(num_errors), EG(errors)); } ZEND_API void zend_free_recorded_errors(void) diff --git a/Zend/zend.h b/Zend/zend.h index 0cf1faeb653..b103faf5ab5 100644 --- a/Zend/zend.h +++ b/Zend/zend.h @@ -444,6 +444,7 @@ ZEND_API void zend_replace_error_handling(zend_error_handling_t error_handling, ZEND_API void zend_restore_error_handling(zend_error_handling *saved); ZEND_API void zend_begin_record_errors(void); ZEND_API void zend_emit_recorded_errors(void); +ZEND_API void zend_emit_recorded_errors_ex(uint32_t num_errors, zend_error_info **errors); ZEND_API void zend_free_recorded_errors(void); END_EXTERN_C() diff --git a/Zend/zend_API.c b/Zend/zend_API.c index 5262cc0b6c9..8ac140cdcef 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -3770,7 +3770,7 @@ static zend_always_inline zend_class_entry *get_scope(zend_execute_data *frame) static bool zend_is_callable_check_class(zend_string *name, zend_class_entry *scope, zend_execute_data *frame, zend_fcall_info_cache *fcc, bool *strict_class, char **error, bool suppress_deprecation) /* {{{ */ { - bool ret = 0; + bool ret = false; zend_class_entry *ce; size_t name_len = ZSTR_LEN(name); zend_string *lcname; @@ -3795,7 +3795,7 @@ static bool zend_is_callable_check_class(zend_string *name, zend_class_entry *sc if (!fcc->object) { fcc->object = zend_get_this_object(frame); } - ret = 1; + ret = true; } } else if (zend_string_equals(lcname, ZSTR_KNOWN(ZEND_STR_PARENT))) { if (!scope) { @@ -3815,7 +3815,7 @@ static bool zend_is_callable_check_class(zend_string *name, zend_class_entry *sc fcc->object = zend_get_this_object(frame); } *strict_class = 1; - ret = 1; + ret = true; } } else if (zend_string_equals(lcname, ZSTR_KNOWN(ZEND_STR_STATIC))) { zend_class_entry *called_scope = zend_get_called_scope(frame); @@ -3832,7 +3832,7 @@ static bool zend_is_callable_check_class(zend_string *name, zend_class_entry *sc fcc->object = zend_get_this_object(frame); } *strict_class = 1; - ret = 1; + ret = true; } } else if ((ce = zend_lookup_class(name)) != NULL) { zend_class_entry *scope = get_scope(frame); @@ -3852,7 +3852,7 @@ static bool zend_is_callable_check_class(zend_string *name, zend_class_entry *sc fcc->called_scope = fcc->object ? fcc->object->ce : ce; } *strict_class = 1; - ret = 1; + ret = true; } else { if (error) zend_spprintf(error, 0, "class \"%.*s\" not found", (int)name_len, ZSTR_VAL(name)); } @@ -5000,7 +5000,7 @@ ZEND_API void zend_declare_class_constant_string(zend_class_entry *ce, const cha } /* }}} */ -ZEND_API void zend_update_property_ex(zend_class_entry *scope, zend_object *object, zend_string *name, zval *value) /* {{{ */ +ZEND_API void zend_update_property_ex(const zend_class_entry *scope, zend_object *object, zend_string *name, zval *value) /* {{{ */ { const zend_class_entry *old_scope = EG(fake_scope); @@ -5012,7 +5012,7 @@ ZEND_API void zend_update_property_ex(zend_class_entry *scope, zend_object *obje } /* }}} */ -ZEND_API void zend_update_property(zend_class_entry *scope, zend_object *object, const char *name, size_t name_length, zval *value) /* {{{ */ +ZEND_API void zend_update_property(const zend_class_entry *scope, zend_object *object, const char *name, size_t name_length, zval *value) /* {{{ */ { zend_string *property; const zend_class_entry *old_scope = EG(fake_scope); @@ -5027,7 +5027,7 @@ ZEND_API void zend_update_property(zend_class_entry *scope, zend_object *object, } /* }}} */ -ZEND_API void zend_update_property_null(zend_class_entry *scope, zend_object *object, const char *name, size_t name_length) /* {{{ */ +ZEND_API void zend_update_property_null(const zend_class_entry *scope, zend_object *object, const char *name, size_t name_length) /* {{{ */ { zval tmp; @@ -5036,7 +5036,7 @@ ZEND_API void zend_update_property_null(zend_class_entry *scope, zend_object *ob } /* }}} */ -ZEND_API void zend_unset_property(zend_class_entry *scope, zend_object *object, const char *name, size_t name_length) /* {{{ */ +ZEND_API void zend_unset_property(const zend_class_entry *scope, zend_object *object, const char *name, size_t name_length) /* {{{ */ { zend_string *property; const zend_class_entry *old_scope = EG(fake_scope); @@ -5051,7 +5051,7 @@ ZEND_API void zend_unset_property(zend_class_entry *scope, zend_object *object, } /* }}} */ -ZEND_API void zend_update_property_bool(zend_class_entry *scope, zend_object *object, const char *name, size_t name_length, zend_long value) /* {{{ */ +ZEND_API void zend_update_property_bool(const zend_class_entry *scope, zend_object *object, const char *name, size_t name_length, zend_long value) /* {{{ */ { zval tmp; @@ -5060,7 +5060,7 @@ ZEND_API void zend_update_property_bool(zend_class_entry *scope, zend_object *ob } /* }}} */ -ZEND_API void zend_update_property_long(zend_class_entry *scope, zend_object *object, const char *name, size_t name_length, zend_long value) /* {{{ */ +ZEND_API void zend_update_property_long(const zend_class_entry *scope, zend_object *object, const char *name, size_t name_length, zend_long value) /* {{{ */ { zval tmp; @@ -5069,7 +5069,7 @@ ZEND_API void zend_update_property_long(zend_class_entry *scope, zend_object *ob } /* }}} */ -ZEND_API void zend_update_property_double(zend_class_entry *scope, zend_object *object, const char *name, size_t name_length, double value) /* {{{ */ +ZEND_API void zend_update_property_double(const zend_class_entry *scope, zend_object *object, const char *name, size_t name_length, double value) /* {{{ */ { zval tmp; @@ -5078,7 +5078,7 @@ ZEND_API void zend_update_property_double(zend_class_entry *scope, zend_object * } /* }}} */ -ZEND_API void zend_update_property_str(zend_class_entry *scope, zend_object *object, const char *name, size_t name_length, zend_string *value) /* {{{ */ +ZEND_API void zend_update_property_str(const zend_class_entry *scope, zend_object *object, const char *name, size_t name_length, zend_string *value) /* {{{ */ { zval tmp; @@ -5087,7 +5087,7 @@ ZEND_API void zend_update_property_str(zend_class_entry *scope, zend_object *obj } /* }}} */ -ZEND_API void zend_update_property_string(zend_class_entry *scope, zend_object *object, const char *name, size_t name_length, const char *value) /* {{{ */ +ZEND_API void zend_update_property_string(const zend_class_entry *scope, zend_object *object, const char *name, size_t name_length, const char *value) /* {{{ */ { zval tmp; @@ -5097,7 +5097,7 @@ ZEND_API void zend_update_property_string(zend_class_entry *scope, zend_object * } /* }}} */ -ZEND_API void zend_update_property_stringl(zend_class_entry *scope, zend_object *object, const char *name, size_t name_length, const char *value, size_t value_len) /* {{{ */ +ZEND_API void zend_update_property_stringl(const zend_class_entry *scope, zend_object *object, const char *name, size_t name_length, const char *value, size_t value_len) /* {{{ */ { zval tmp; diff --git a/Zend/zend_API.h b/Zend/zend_API.h index 25a96f8cc9e..78a30d630ae 100644 --- a/Zend/zend_API.h +++ b/Zend/zend_API.h @@ -494,16 +494,16 @@ static zend_always_inline HashTable *zend_class_backed_enum_table(zend_class_ent } } -ZEND_API void zend_update_property_ex(zend_class_entry *scope, zend_object *object, zend_string *name, zval *value); -ZEND_API void zend_update_property(zend_class_entry *scope, zend_object *object, const char *name, size_t name_length, zval *value); -ZEND_API void zend_update_property_null(zend_class_entry *scope, zend_object *object, const char *name, size_t name_length); -ZEND_API void zend_update_property_bool(zend_class_entry *scope, zend_object *object, const char *name, size_t name_length, zend_long value); -ZEND_API void zend_update_property_long(zend_class_entry *scope, zend_object *object, const char *name, size_t name_length, zend_long value); -ZEND_API void zend_update_property_double(zend_class_entry *scope, zend_object *object, const char *name, size_t name_length, double value); -ZEND_API void zend_update_property_str(zend_class_entry *scope, zend_object *object, const char *name, size_t name_length, zend_string *value); -ZEND_API void zend_update_property_string(zend_class_entry *scope, zend_object *object, const char *name, size_t name_length, const char *value); -ZEND_API void zend_update_property_stringl(zend_class_entry *scope, zend_object *object, const char *name, size_t name_length, const char *value, size_t value_length); -ZEND_API void zend_unset_property(zend_class_entry *scope, zend_object *object, const char *name, size_t name_length); +ZEND_API void zend_update_property_ex(const zend_class_entry *scope, zend_object *object, zend_string *name, zval *value); +ZEND_API void zend_update_property(const zend_class_entry *scope, zend_object *object, const char *name, size_t name_length, zval *value); +ZEND_API void zend_update_property_null(const zend_class_entry *scope, zend_object *object, const char *name, size_t name_length); +ZEND_API void zend_update_property_bool(const zend_class_entry *scope, zend_object *object, const char *name, size_t name_length, zend_long value); +ZEND_API void zend_update_property_long(const zend_class_entry *scope, zend_object *object, const char *name, size_t name_length, zend_long value); +ZEND_API void zend_update_property_double(const zend_class_entry *scope, zend_object *object, const char *name, size_t name_length, double value); +ZEND_API void zend_update_property_str(const zend_class_entry *scope, zend_object *object, const char *name, size_t name_length, zend_string *value); +ZEND_API void zend_update_property_string(const zend_class_entry *scope, zend_object *object, const char *name, size_t name_length, const char *value); +ZEND_API void zend_update_property_stringl(const zend_class_entry *scope, zend_object *object, const char *name, size_t name_length, const char *value, size_t value_length); +ZEND_API void zend_unset_property(const zend_class_entry *scope, zend_object *object, const char *name, size_t name_length); ZEND_API zend_result zend_update_static_property_ex(zend_class_entry *scope, zend_string *name, zval *value); ZEND_API zend_result zend_update_static_property(zend_class_entry *scope, const char *name, size_t name_length, zval *value); @@ -2326,7 +2326,7 @@ static zend_always_inline bool zend_parse_arg_string(zval *arg, char **dest, siz static zend_always_inline bool zend_parse_arg_path_str(zval *arg, zend_string **dest, bool check_null, uint32_t arg_num) { if (!zend_parse_arg_str(arg, dest, check_null, arg_num) || - (*dest && UNEXPECTED(CHECK_NULL_PATH(ZSTR_VAL(*dest), ZSTR_LEN(*dest))))) { + (*dest && UNEXPECTED(zend_str_has_nul_byte(*dest)))) { return 0; } return 1; diff --git a/Zend/zend_alloc.c b/Zend/zend_alloc.c index f2f801db633..edadf024df2 100644 --- a/Zend/zend_alloc.c +++ b/Zend/zend_alloc.c @@ -317,7 +317,9 @@ struct _zend_mm_heap { } debug; }; #endif +#if ZEND_DEBUG pid_t pid; +#endif zend_random_bytes_insecure_state rand_state; }; @@ -1310,15 +1312,20 @@ static zend_always_inline zend_mm_free_slot* zend_mm_encode_free_slot(const zend #endif } -static zend_always_inline zend_mm_free_slot* zend_mm_decode_free_slot(zend_mm_heap *heap, zend_mm_free_slot *slot) +static zend_always_inline zend_mm_free_slot* zend_mm_decode_free_slot_key(uintptr_t shadow_key, zend_mm_free_slot *slot) { #ifdef WORDS_BIGENDIAN - return (zend_mm_free_slot*)((uintptr_t)slot ^ heap->shadow_key); + return (zend_mm_free_slot*)((uintptr_t)slot ^ shadow_key); #else - return (zend_mm_free_slot*)(BSWAPPTR((uintptr_t)slot ^ heap->shadow_key)); + return (zend_mm_free_slot*)(BSWAPPTR((uintptr_t)slot ^ shadow_key)); #endif } +static zend_always_inline zend_mm_free_slot* zend_mm_decode_free_slot(zend_mm_heap *heap, zend_mm_free_slot *slot) +{ + return zend_mm_decode_free_slot_key(heap->shadow_key, slot); +} + static zend_always_inline void zend_mm_set_next_free_slot(zend_mm_heap *heap, uint32_t bin_num, zend_mm_free_slot *slot, zend_mm_free_slot *next) { ZEND_ASSERT(bin_data_size[bin_num] >= ZEND_MM_MIN_USEABLE_BIN_SIZE); @@ -2027,6 +2034,34 @@ static void zend_mm_init_key(zend_mm_heap *heap) zend_mm_refresh_key(heap); } +ZEND_API void zend_mm_refresh_key_child(zend_mm_heap *heap) +{ + uintptr_t old_key = heap->shadow_key; + + zend_mm_init_key(heap); + + /* Update shadow pointers with new key */ + for (int i = 0; i < ZEND_MM_BINS; i++) { + zend_mm_free_slot *slot = heap->free_slot[i]; + if (!slot) { + continue; + } + zend_mm_free_slot *next; + while ((next = slot->next_free_slot)) { + zend_mm_free_slot *shadow = ZEND_MM_FREE_SLOT_PTR_SHADOW(slot, i); + if (UNEXPECTED(next != zend_mm_decode_free_slot_key(old_key, shadow))) { + zend_mm_panic("zend_mm_heap corrupted"); + } + zend_mm_set_next_free_slot(heap, i, slot, next); + slot = next; + } + } + +#if ZEND_DEBUG + heap->pid = getpid(); +#endif +} + static zend_mm_heap *zend_mm_init(void) { zend_mm_chunk *chunk = (zend_mm_chunk*)zend_mm_chunk_alloc_int(ZEND_MM_CHUNK_SIZE, ZEND_MM_CHUNK_SIZE); @@ -2075,7 +2110,9 @@ static zend_mm_heap *zend_mm_init(void) heap->storage = NULL; #endif heap->huge_list = NULL; +#if ZEND_DEBUG heap->pid = getpid(); +#endif return heap; } @@ -2535,13 +2572,12 @@ ZEND_API void zend_mm_shutdown(zend_mm_heap *heap, bool full, bool silent) p->free_map[0] = (1L << ZEND_MM_FIRST_PAGE) - 1; p->map[0] = ZEND_MM_LRUN(ZEND_MM_FIRST_PAGE); - pid_t pid = getpid(); - if (heap->pid != pid) { - zend_mm_init_key(heap); - heap->pid = pid; - } else { - zend_mm_refresh_key(heap); - } +#if ZEND_DEBUG + ZEND_ASSERT(getpid() == heap->pid + && "heap was re-used without calling zend_mm_refresh_key_child() after a fork"); +#endif + + zend_mm_refresh_key(heap); } } @@ -2949,6 +2985,11 @@ ZEND_API void shutdown_memory_manager(bool silent, bool full_shutdown) zend_mm_shutdown(AG(mm_heap), full_shutdown, silent); } +ZEND_API void refresh_memory_manager(void) +{ + zend_mm_refresh_key_child(AG(mm_heap)); +} + static ZEND_COLD ZEND_NORETURN void zend_out_of_memory(void) { fprintf(stderr, "Out of memory\n"); @@ -3506,7 +3547,9 @@ ZEND_API zend_mm_heap *zend_mm_startup_ex(const zend_mm_handlers *handlers, void memcpy(storage->data, data, data_size); } heap->storage = storage; +#if ZEND_DEBUG heap->pid = getpid(); +#endif return heap; #else return NULL; diff --git a/Zend/zend_alloc.h b/Zend/zend_alloc.h index 541989a2a13..264e13848d1 100644 --- a/Zend/zend_alloc.h +++ b/Zend/zend_alloc.h @@ -220,6 +220,7 @@ ZEND_API bool zend_alloc_in_memory_limit_error_reporting(void); ZEND_API void start_memory_manager(void); ZEND_API void shutdown_memory_manager(bool silent, bool full_shutdown); +ZEND_API void refresh_memory_manager(void); ZEND_API bool is_zend_mm(void); ZEND_API bool is_zend_ptr(const void *ptr); @@ -316,6 +317,8 @@ struct _zend_mm_storage { ZEND_API zend_mm_storage *zend_mm_get_storage(zend_mm_heap *heap); ZEND_API zend_mm_heap *zend_mm_startup_ex(const zend_mm_handlers *handlers, void *data, size_t data_size); +ZEND_API void zend_mm_refresh_key_child(zend_mm_heap *heap); + /* // The following example shows how to use zend_mm_heap API with custom storage diff --git a/Zend/zend_ast.c b/Zend/zend_ast.c index 0e403329264..1172cba2d4f 100644 --- a/Zend/zend_ast.c +++ b/Zend/zend_ast.c @@ -33,7 +33,7 @@ static inline void *zend_ast_alloc(size_t size) { return zend_arena_alloc(&CG(ast_arena), size); } -static inline void *zend_ast_realloc(void *old, size_t old_size, size_t new_size) { +static inline void *zend_ast_realloc(const void *old, size_t old_size, size_t new_size) { void *new = zend_ast_alloc(new_size); memcpy(new, old, old_size); return new; @@ -43,7 +43,7 @@ static inline size_t zend_ast_list_size(uint32_t children) { return sizeof(zend_ast_list) - sizeof(zend_ast *) + sizeof(zend_ast *) * children; } -ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_znode(znode *node) { +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_znode(const znode *node) { zend_ast_znode *ast; ast = zend_ast_alloc(sizeof(zend_ast_znode)); @@ -66,7 +66,7 @@ ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_fcc(void) { return (zend_ast *) ast; } -static zend_always_inline zend_ast * zend_ast_create_zval_int(zval *zv, uint32_t attr, uint32_t lineno) { +static zend_always_inline zend_ast * zend_ast_create_zval_int(const zval *zv, uint32_t attr, uint32_t lineno) { zend_ast_zval *ast; ast = zend_ast_alloc(sizeof(zend_ast_zval)); @@ -77,15 +77,15 @@ static zend_always_inline zend_ast * zend_ast_create_zval_int(zval *zv, uint32_t return (zend_ast *) ast; } -ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_zval_with_lineno(zval *zv, uint32_t lineno) { +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_zval_with_lineno(const zval *zv, uint32_t lineno) { return zend_ast_create_zval_int(zv, 0, lineno); } -ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_zval_ex(zval *zv, zend_ast_attr attr) { +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_zval_ex(const zval *zv, zend_ast_attr attr) { return zend_ast_create_zval_int(zv, attr, CG(zend_lineno)); } -ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_zval(zval *zv) { +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_zval(const zval *zv) { return zend_ast_create_zval_int(zv, 0, CG(zend_lineno)); } @@ -508,7 +508,7 @@ ZEND_API zend_ast * ZEND_FASTCALL zend_ast_list_add(zend_ast *ast, zend_ast *op) return (zend_ast *) list; } -static zend_result zend_ast_add_array_element(zval *result, zval *offset, zval *expr) +static zend_result zend_ast_add_array_element(const zval *result, zval *offset, zval *expr) { if (Z_TYPE_P(offset) == IS_UNDEF) { if (!zend_hash_next_index_insert(Z_ARRVAL_P(result), expr)) { @@ -528,9 +528,9 @@ static zend_result zend_ast_add_array_element(zval *result, zval *offset, zval * return SUCCESS; } -static zend_result zend_ast_add_unpacked_element(zval *result, zval *expr) { +static zend_result zend_ast_add_unpacked_element(const zval *result, const zval *expr) { if (EXPECTED(Z_TYPE_P(expr) == IS_ARRAY)) { - HashTable *ht = Z_ARRVAL_P(expr); + const HashTable *ht = Z_ARRVAL_P(expr); zval *val; zend_string *key; @@ -610,9 +610,10 @@ ZEND_API zend_result ZEND_FASTCALL zend_ast_evaluate_inner( ret = FAILURE; } else { binary_op_type op = get_binary_op(ast->attr); - ret = op(result, &op1, &op2); + op(result, &op1, &op2); zval_ptr_dtor_nogc(&op1); zval_ptr_dtor_nogc(&op2); + ret = EG(exception) ? FAILURE : SUCCESS; } break; case ZEND_AST_GREATER: @@ -1242,7 +1243,7 @@ static size_t ZEND_FASTCALL zend_ast_tree_size(zend_ast *ast) size = sizeof(zend_ast_fcc); } else if (zend_ast_is_list(ast)) { uint32_t i; - zend_ast_list *list = zend_ast_get_list(ast); + const zend_ast_list *list = zend_ast_get_list(ast); size = zend_ast_list_size(list->children); for (i = 0; i < list->children; i++) { @@ -1283,7 +1284,7 @@ static void* ZEND_FASTCALL zend_ast_tree_copy(zend_ast *ast, void *buf) Z_LINENO(new->val) = zend_ast_get_lineno(ast); buf = (void*)((char*)buf + sizeof(zend_ast_zval)); } else if (zend_ast_is_list(ast)) { - zend_ast_list *list = zend_ast_get_list(ast); + const zend_ast_list *list = zend_ast_get_list(ast); zend_ast_list *new = (zend_ast_list*)buf; uint32_t i; new->kind = list->kind; @@ -1300,7 +1301,7 @@ static void* ZEND_FASTCALL zend_ast_tree_copy(zend_ast *ast, void *buf) } } } else if (ast->kind == ZEND_AST_OP_ARRAY) { - zend_ast_op_array *old = zend_ast_get_op_array(ast); + const zend_ast_op_array *old = zend_ast_get_op_array(ast); zend_ast_op_array *new = (zend_ast_op_array*)buf; new->kind = old->kind; new->attr = old->attr; @@ -1309,7 +1310,7 @@ static void* ZEND_FASTCALL zend_ast_tree_copy(zend_ast *ast, void *buf) function_add_ref((zend_function *)new->op_array); buf = (void*)((char*)buf + sizeof(zend_ast_op_array)); } else if (ast->kind == ZEND_AST_CALLABLE_CONVERT) { - zend_ast_fcc *old = (zend_ast_fcc*)ast; + const zend_ast_fcc *old = (zend_ast_fcc*)ast; zend_ast_fcc *new = (zend_ast_fcc*)buf; new->kind = old->kind; new->attr = old->attr; @@ -1370,7 +1371,7 @@ tail_call: } else if (EXPECTED(ast->kind == ZEND_AST_ZVAL)) { zval_ptr_dtor_nogc(zend_ast_get_zval(ast)); } else if (EXPECTED(zend_ast_is_list(ast))) { - zend_ast_list *list = zend_ast_get_list(ast); + const zend_ast_list *list = zend_ast_get_list(ast); if (list->children) { uint32_t i; @@ -1385,7 +1386,7 @@ tail_call: } else if (EXPECTED(ast->kind == ZEND_AST_OP_ARRAY)) { destroy_op_array(zend_ast_get_op_array(ast)->op_array); } else if (EXPECTED(zend_ast_is_decl(ast))) { - zend_ast_decl *decl = (zend_ast_decl *) ast; + const zend_ast_decl *decl = (const zend_ast_decl *) ast; if (decl->name) { zend_string_release_ex(decl->name, 0); @@ -1464,7 +1465,7 @@ ZEND_API void zend_ast_apply(zend_ast *ast, zend_ast_apply_func fn, void *contex static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int priority, int indent); -static ZEND_COLD void zend_ast_export_str(smart_str *str, zend_string *s) +static ZEND_COLD void zend_ast_export_str(smart_str *str, const zend_string *s) { size_t i; @@ -1479,7 +1480,7 @@ static ZEND_COLD void zend_ast_export_str(smart_str *str, zend_string *s) } } -static ZEND_COLD void zend_ast_export_qstr(smart_str *str, char quote, zend_string *s) +static ZEND_COLD void zend_ast_export_qstr(smart_str *str, char quote, const zend_string *s) { size_t i; @@ -1535,7 +1536,7 @@ static ZEND_COLD void zend_ast_export_indent(smart_str *str, int indent) static ZEND_COLD void zend_ast_export_name(smart_str *str, zend_ast *ast, int priority, int indent) { if (ast->kind == ZEND_AST_ZVAL) { - zval *zv = zend_ast_get_zval(ast); + const zval *zv = zend_ast_get_zval(ast); if (Z_TYPE_P(zv) == IS_STRING) { smart_str_append(str, Z_STR_P(zv)); @@ -1548,7 +1549,7 @@ static ZEND_COLD void zend_ast_export_name(smart_str *str, zend_ast *ast, int pr static ZEND_COLD void zend_ast_export_ns_name(smart_str *str, zend_ast *ast, int priority, int indent) { if (ast->kind == ZEND_AST_ZVAL) { - zval *zv = zend_ast_get_zval(ast); + const zval *zv = zend_ast_get_zval(ast); if (Z_TYPE_P(zv) == IS_STRING) { if (ast->attr == ZEND_NAME_FQ) { @@ -1627,7 +1628,7 @@ static ZEND_COLD void zend_ast_export_var(smart_str *str, zend_ast *ast, int pri /* Use zend_ast_export_list() unless fewer than `list->children` children should * be exported. */ -static ZEND_COLD void zend_ast_export_list_ex(smart_str *str, zend_ast_list *list, bool separator, int priority, int indent, int children) +static ZEND_COLD void zend_ast_export_list_ex(smart_str *str, const zend_ast_list *list, bool separator, int priority, int indent, uint32_t children) { ZEND_ASSERT(children <= list->children); uint32_t i = 0; @@ -1641,12 +1642,12 @@ static ZEND_COLD void zend_ast_export_list_ex(smart_str *str, zend_ast_list *lis } } -static ZEND_COLD void zend_ast_export_list(smart_str *str, zend_ast_list *list, bool separator, int priority, int indent) +static ZEND_COLD void zend_ast_export_list(smart_str *str, const zend_ast_list *list, bool separator, int priority, int indent) { zend_ast_export_list_ex(str, list, separator, priority, indent, list->children); } -static ZEND_COLD void zend_ast_export_encaps_list(smart_str *str, char quote, zend_ast_list *list, int indent) +static ZEND_COLD void zend_ast_export_encaps_list(smart_str *str, char quote, const zend_ast_list *list, int indent) { uint32_t i = 0; zend_ast *ast; @@ -1654,7 +1655,7 @@ static ZEND_COLD void zend_ast_export_encaps_list(smart_str *str, char quote, ze while (i < list->children) { ast = list->child[i]; if (ast->kind == ZEND_AST_ZVAL) { - zval *zv = zend_ast_get_zval(ast); + const zval *zv = zend_ast_get_zval(ast); ZEND_ASSERT(Z_TYPE_P(zv) == IS_STRING); zend_ast_export_qstr(str, quote, Z_STR_P(zv)); @@ -1675,7 +1676,7 @@ static ZEND_COLD void zend_ast_export_encaps_list(smart_str *str, char quote, ze } } -static ZEND_COLD void zend_ast_export_name_list_ex(smart_str *str, zend_ast_list *list, int indent, const char *separator) +static ZEND_COLD void zend_ast_export_name_list_ex(smart_str *str, const zend_ast_list *list, int indent, const char *separator) { uint32_t i = 0; @@ -1691,7 +1692,7 @@ static ZEND_COLD void zend_ast_export_name_list_ex(smart_str *str, zend_ast_list #define zend_ast_export_name_list(s, l, i) zend_ast_export_name_list_ex(s, l, i, ", ") #define zend_ast_export_catch_name_list(s, l, i) zend_ast_export_name_list_ex(s, l, i, "|") -static ZEND_COLD void zend_ast_export_var_list(smart_str *str, zend_ast_list *list, int indent) +static ZEND_COLD void zend_ast_export_var_list(smart_str *str, const zend_ast_list *list, int indent) { uint32_t i = 0; @@ -1716,7 +1717,7 @@ static ZEND_COLD void zend_ast_export_stmt(smart_str *str, zend_ast *ast, int in if (ast->kind == ZEND_AST_STMT_LIST || ast->kind == ZEND_AST_TRAIT_ADAPTATIONS) { - zend_ast_list *list = (zend_ast_list*)ast; + const zend_ast_list *list = (const zend_ast_list*)ast; uint32_t i = 0; while (i < list->children) { @@ -1743,8 +1744,8 @@ static ZEND_COLD void zend_ast_export_stmt(smart_str *str, zend_ast *ast, int in case ZEND_AST_DECLARE: break; case ZEND_AST_PROP_GROUP: { - zend_ast *first_prop = zend_ast_get_list(ast->child[1])->child[0]; - zend_ast *hook_list = first_prop->child[3]; + const zend_ast *first_prop = zend_ast_get_list(ast->child[1])->child[0]; + const zend_ast *hook_list = first_prop->child[3]; if (hook_list == NULL) { smart_str_appendc(str, ';'); } @@ -1758,7 +1759,7 @@ static ZEND_COLD void zend_ast_export_stmt(smart_str *str, zend_ast *ast, int in } } -static ZEND_COLD void zend_ast_export_if_stmt(smart_str *str, zend_ast_list *list, int indent) +static ZEND_COLD void zend_ast_export_if_stmt(smart_str *str, const zend_ast_list *list, int indent) { uint32_t i; zend_ast *ast; @@ -1782,7 +1783,7 @@ tail_call: zend_ast_export_indent(str, indent); smart_str_appends(str, "} else "); if (ast->child[1] && ast->child[1]->kind == ZEND_AST_IF) { - list = (zend_ast_list*)ast->child[1]; + list = (const zend_ast_list*)ast->child[1]; goto tail_call; } else { smart_str_appends(str, "{\n"); @@ -1795,7 +1796,7 @@ tail_call: smart_str_appendc(str, '}'); } -static ZEND_COLD void zend_ast_export_zval(smart_str *str, zval *zv, int priority, int indent) +static ZEND_COLD void zend_ast_export_zval(smart_str *str, const zval *zv, int priority, int indent) { ZVAL_DEREF(zv); switch (Z_TYPE_P(zv)) { @@ -1852,7 +1853,7 @@ static ZEND_COLD void zend_ast_export_zval(smart_str *str, zval *zv, int priorit } } -static ZEND_COLD void zend_ast_export_class_no_header(smart_str *str, zend_ast_decl *decl, int indent) { +static ZEND_COLD void zend_ast_export_class_no_header(smart_str *str, const zend_ast_decl *decl, int indent) { if (decl->child[0]) { smart_str_appends(str, " extends "); zend_ast_export_ns_name(str, decl->child[0], 0, indent); @@ -1868,9 +1869,9 @@ static ZEND_COLD void zend_ast_export_class_no_header(smart_str *str, zend_ast_d } static ZEND_COLD void zend_ast_export_attribute_group(smart_str *str, zend_ast *ast, int indent) { - zend_ast_list *list = zend_ast_get_list(ast); + const zend_ast_list *list = zend_ast_get_list(ast); for (uint32_t i = 0; i < list->children; i++) { - zend_ast *attr = list->child[i]; + const zend_ast *attr = list->child[i]; if (i) { smart_str_appends(str, ", "); @@ -1886,7 +1887,7 @@ static ZEND_COLD void zend_ast_export_attribute_group(smart_str *str, zend_ast * } static ZEND_COLD void zend_ast_export_attributes(smart_str *str, zend_ast *ast, int indent, bool newlines) { - zend_ast_list *list = zend_ast_get_list(ast); + const zend_ast_list *list = zend_ast_get_list(ast); uint32_t i; for (i = 0; i < list->children; i++) { @@ -1925,7 +1926,7 @@ static ZEND_COLD void zend_ast_export_visibility(smart_str *str, uint32_t flags, static ZEND_COLD void zend_ast_export_type(smart_str *str, zend_ast *ast, int indent) { if (ast->kind == ZEND_AST_TYPE_UNION) { - zend_ast_list *list = zend_ast_get_list(ast); + const zend_ast_list *list = zend_ast_get_list(ast); for (uint32_t i = 0; i < list->children; i++) { if (i != 0) { smart_str_appendc(str, '|'); @@ -1935,7 +1936,7 @@ static ZEND_COLD void zend_ast_export_type(smart_str *str, zend_ast *ast, int in return; } if (ast->kind == ZEND_AST_TYPE_INTERSECTION) { - zend_ast_list *list = zend_ast_get_list(ast); + const zend_ast_list *list = zend_ast_get_list(ast); for (uint32_t i = 0; i < list->children; i++) { if (i != 0) { smart_str_appendc(str, '&'); @@ -1950,7 +1951,7 @@ static ZEND_COLD void zend_ast_export_type(smart_str *str, zend_ast *ast, int in zend_ast_export_ns_name(str, ast, 0, indent); } -static ZEND_COLD void zend_ast_export_hook_list(smart_str *str, zend_ast_list *hook_list, int indent) +static ZEND_COLD void zend_ast_export_hook_list(smart_str *str, const zend_ast_list *hook_list, int indent) { smart_str_appends(str, " {"); smart_str_appendc(str, '\n'); @@ -1958,7 +1959,7 @@ static ZEND_COLD void zend_ast_export_hook_list(smart_str *str, zend_ast_list *h zend_ast_export_indent(str, indent); for (uint32_t i = 0; i < hook_list->children; i++) { - zend_ast_decl *hook = (zend_ast_decl *)hook_list->child[i]; + const zend_ast_decl *hook = (const zend_ast_decl *)hook_list->child[i]; zend_ast_export_visibility(str, hook->flags, ZEND_MODIFIER_TARGET_PROPERTY); if (hook->flags & ZEND_ACC_FINAL) { smart_str_appends(str, "final "); @@ -2032,7 +2033,7 @@ static ZEND_COLD void zend_ast_export_hook_list(smart_str *str, zend_ast_list *h static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int priority, int indent) { - zend_ast_decl *decl; + const zend_ast_decl *decl; int p, pl, pr; const char *op; @@ -2068,7 +2069,7 @@ tail_call: case ZEND_AST_CLOSURE: case ZEND_AST_ARROW_FUNC: case ZEND_AST_METHOD: - decl = (zend_ast_decl *) ast; + decl = (const zend_ast_decl *) ast; if (decl->child[4]) { bool newlines = !(ast->kind == ZEND_AST_CLOSURE || ast->kind == ZEND_AST_ARROW_FUNC); zend_ast_export_attributes(str, decl->child[4], indent, newlines); @@ -2127,7 +2128,7 @@ tail_call: } break; case ZEND_AST_CLASS: - decl = (zend_ast_decl *) ast; + decl = (const zend_ast_decl *) ast; if (decl->child[3]) { zend_ast_export_attributes(str, decl->child[3], indent, 1); } @@ -2163,16 +2164,16 @@ tail_call: case ZEND_AST_EXPR_LIST: case ZEND_AST_PARAM_LIST: simple_list: - zend_ast_export_list(str, (zend_ast_list*)ast, 1, 20, indent); + zend_ast_export_list(str, zend_ast_get_list(ast), 1, 20, indent); break; case ZEND_AST_ARRAY: smart_str_appendc(str, '['); - zend_ast_export_list(str, (zend_ast_list*)ast, 1, 20, indent); + zend_ast_export_list(str, zend_ast_get_list(ast), 1, 20, indent); smart_str_appendc(str, ']'); break; case ZEND_AST_ENCAPS_LIST: smart_str_appendc(str, '"'); - zend_ast_export_encaps_list(str, '"', (zend_ast_list*)ast, indent); + zend_ast_export_encaps_list(str, '"', zend_ast_get_list(ast), indent); smart_str_appendc(str, '"'); break; case ZEND_AST_STMT_LIST: @@ -2180,16 +2181,16 @@ simple_list: zend_ast_export_stmt(str, ast, indent); break; case ZEND_AST_IF: - zend_ast_export_if_stmt(str, (zend_ast_list*)ast, indent); + zend_ast_export_if_stmt(str, zend_ast_get_list(ast), indent); break; case ZEND_AST_SWITCH_LIST: case ZEND_AST_CATCH_LIST: case ZEND_AST_MATCH_ARM_LIST: - zend_ast_export_list(str, (zend_ast_list*)ast, 0, 0, indent); + zend_ast_export_list(str, zend_ast_get_list(ast), 0, 0, indent); break; case ZEND_AST_CLOSURE_USES: smart_str_appends(str, " use("); - zend_ast_export_var_list(str, (zend_ast_list*)ast, indent); + zend_ast_export_var_list(str, zend_ast_get_list(ast), indent); smart_str_appendc(str, ')'); break; case ZEND_AST_PROP_GROUP: { @@ -2254,7 +2255,7 @@ simple_list: goto simple_list; case ZEND_AST_NAME_LIST: - zend_ast_export_name_list(str, (zend_ast_list*)ast, indent); + zend_ast_export_name_list(str, zend_ast_get_list(ast), indent); break; case ZEND_AST_USE: smart_str_appends(str, "use "); @@ -2309,7 +2310,7 @@ simple_list: case IS_NULL: PREFIX_OP("(unset)", 240, 241); case _IS_BOOL: PREFIX_OP("(bool)", 240, 241); case IS_LONG: PREFIX_OP("(int)", 240, 241); - case IS_DOUBLE: PREFIX_OP("(double)", 240, 241); + case IS_DOUBLE: PREFIX_OP("(float)", 240, 241); case IS_STRING: PREFIX_OP("(string)", 240, 241); case IS_ARRAY: PREFIX_OP("(array)", 240, 241); case IS_OBJECT: PREFIX_OP("(object)", 240, 241); @@ -2328,7 +2329,7 @@ simple_list: case ZEND_AST_SHELL_EXEC: smart_str_appendc(str, '`'); if (ast->child[0]->kind == ZEND_AST_ENCAPS_LIST) { - zend_ast_export_encaps_list(str, '`', (zend_ast_list*)ast->child[0], indent); + zend_ast_export_encaps_list(str, '`', zend_ast_get_list(ast->child[0]), indent); } else { zval *zv; ZEND_ASSERT(ast->child[0]->kind == ZEND_AST_ZVAL); @@ -2522,7 +2523,7 @@ simple_list: case ZEND_AST_NEW: smart_str_appends(str, "new "); if (ast->child[0]->kind == ZEND_AST_CLASS) { - zend_ast_decl *decl = (zend_ast_decl *) ast->child[0]; + const zend_ast_decl *decl = (const zend_ast_decl *) ast->child[0]; if (decl->child[3]) { zend_ast_export_attributes(str, decl->child[3], indent, 0); } @@ -2625,7 +2626,7 @@ simple_list: case ZEND_AST_MATCH_ARM: zend_ast_export_indent(str, indent); if (ast->child[0]) { - zend_ast_export_list(str, (zend_ast_list*)ast->child[0], 1, 0, indent); + zend_ast_export_list(str, zend_ast_get_list(ast->child[0]), 1, 0, indent); smart_str_appends(str, " => "); } else { smart_str_appends(str, "default => "); @@ -2636,7 +2637,7 @@ simple_list: case ZEND_AST_DECLARE: smart_str_appends(str, "declare("); ZEND_ASSERT(ast->child[0]->kind == ZEND_AST_CONST_DECL); - zend_ast_export_list(str, (zend_ast_list*)ast->child[0], 1, 0, indent); + zend_ast_export_list(str, zend_ast_get_list(ast->child[0]), 1, 0, indent); smart_str_appendc(str, ')'); if (ast->child[1]) { smart_str_appends(str, " {\n"); diff --git a/Zend/zend_ast.h b/Zend/zend_ast.h index 08400cff5dd..2e561f22591 100644 --- a/Zend/zend_ast.h +++ b/Zend/zend_ast.h @@ -239,9 +239,9 @@ typedef struct _zend_ast_fcc { typedef void (*zend_ast_process_t)(zend_ast *ast); extern ZEND_API zend_ast_process_t zend_ast_process; -ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_zval_with_lineno(zval *zv, uint32_t lineno); -ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_zval_ex(zval *zv, zend_ast_attr attr); -ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_zval(zval *zv); +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_zval_with_lineno(const zval *zv, uint32_t lineno); +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_zval_ex(const zval *zv, zend_ast_attr attr); +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_zval(const zval *zv); ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_zval_from_str(zend_string *str); ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_zval_from_long(zend_long lval); @@ -348,15 +348,15 @@ static zend_always_inline size_t zend_ast_size(uint32_t children) { return XtOffsetOf(zend_ast, child) + (sizeof(zend_ast *) * children); } -static zend_always_inline bool zend_ast_is_special(zend_ast *ast) { +static zend_always_inline bool zend_ast_is_special(const zend_ast *ast) { return (ast->kind >> ZEND_AST_SPECIAL_SHIFT) & 1; } -static zend_always_inline bool zend_ast_is_decl(zend_ast *ast) { +static zend_always_inline bool zend_ast_is_decl(const zend_ast *ast) { return zend_ast_is_special(ast) && ast->kind >= ZEND_AST_FUNC_DECL; } -static zend_always_inline bool zend_ast_is_list(zend_ast *ast) { +static zend_always_inline bool zend_ast_is_list(const zend_ast *ast) { return (ast->kind >> ZEND_AST_IS_LIST_SHIFT) & 1; } static zend_always_inline zend_ast_list *zend_ast_get_list(zend_ast *ast) { @@ -369,7 +369,7 @@ static zend_always_inline zval *zend_ast_get_zval(zend_ast *ast) { return &((zend_ast_zval *) ast)->val; } static zend_always_inline zend_string *zend_ast_get_str(zend_ast *ast) { - zval *zv = zend_ast_get_zval(ast); + const zval *zv = zend_ast_get_zval(ast); ZEND_ASSERT(Z_TYPE_P(zv) == IS_STRING); return Z_STR_P(zv); } @@ -385,7 +385,7 @@ static zend_always_inline zend_string *zend_ast_get_constant_name(zend_ast *ast) return Z_STR(((zend_ast_zval *) ast)->val); } -static zend_always_inline uint32_t zend_ast_get_num_children(zend_ast *ast) { +static zend_always_inline uint32_t zend_ast_get_num_children(const zend_ast *ast) { ZEND_ASSERT(!zend_ast_is_list(ast)); ZEND_ASSERT(!zend_ast_is_special(ast)); @@ -393,10 +393,10 @@ static zend_always_inline uint32_t zend_ast_get_num_children(zend_ast *ast) { } static zend_always_inline uint32_t zend_ast_get_lineno(zend_ast *ast) { if (ast->kind == ZEND_AST_ZVAL) { - zval *zv = zend_ast_get_zval(ast); + const zval *zv = zend_ast_get_zval(ast); return Z_LINENO_P(zv); } else if (ast->kind == ZEND_AST_CONSTANT) { - zval *zv = &((zend_ast_zval *) ast)->val; + const zval *zv = &((const zend_ast_zval *) ast)->val; return Z_LINENO_P(zv); } else { return ast->lineno; diff --git a/Zend/zend_attributes.c b/Zend/zend_attributes.c index c3633801be8..3256e220d8f 100644 --- a/Zend/zend_attributes.c +++ b/Zend/zend_attributes.c @@ -73,28 +73,46 @@ static void validate_allow_dynamic_properties( zend_attribute *attr, uint32_t target, zend_class_entry *scope) { if (scope->ce_flags & ZEND_ACC_TRAIT) { - zend_error_noreturn(E_ERROR, "Cannot apply #[AllowDynamicProperties] to trait %s", + zend_error_noreturn(E_ERROR, "Cannot apply #[\\AllowDynamicProperties] to trait %s", ZSTR_VAL(scope->name) ); } if (scope->ce_flags & ZEND_ACC_INTERFACE) { - zend_error_noreturn(E_ERROR, "Cannot apply #[AllowDynamicProperties] to interface %s", + zend_error_noreturn(E_ERROR, "Cannot apply #[\\AllowDynamicProperties] to interface %s", ZSTR_VAL(scope->name) ); } if (scope->ce_flags & ZEND_ACC_READONLY_CLASS) { - zend_error_noreturn(E_ERROR, "Cannot apply #[AllowDynamicProperties] to readonly class %s", + zend_error_noreturn(E_ERROR, "Cannot apply #[\\AllowDynamicProperties] to readonly class %s", ZSTR_VAL(scope->name) ); } if (scope->ce_flags & ZEND_ACC_ENUM) { - zend_error_noreturn(E_ERROR, "Cannot apply #[AllowDynamicProperties] to enum %s", + zend_error_noreturn(E_ERROR, "Cannot apply #[\\AllowDynamicProperties] to enum %s", ZSTR_VAL(scope->name) ); } scope->ce_flags |= ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES; } +static void validate_attribute( + zend_attribute *attr, uint32_t target, zend_class_entry *scope) +{ + const char *msg = NULL; + if (scope->ce_flags & ZEND_ACC_TRAIT) { + msg = "Cannot apply #[\\Attribute] to trait %s"; + } else if (scope->ce_flags & ZEND_ACC_INTERFACE) { + msg = "Cannot apply #[\\Attribute] to interface %s"; + } else if (scope->ce_flags & ZEND_ACC_ENUM) { + msg = "Cannot apply #[\\Attribute] to enum %s"; + } else if (scope->ce_flags & ZEND_ACC_EXPLICIT_ABSTRACT_CLASS) { + msg = "Cannot apply #[\\Attribute] to abstract class %s"; + } + if (msg != NULL) { + zend_error_noreturn(E_ERROR, msg, ZSTR_VAL(scope->name)); + } +} + ZEND_METHOD(Attribute, __construct) { zend_long flags = ZEND_ATTRIBUTE_TARGET_ALL; @@ -522,6 +540,7 @@ void zend_register_attribute_ce(void) zend_ce_attribute = register_class_Attribute(); attr = zend_mark_internal_attribute(zend_ce_attribute); + attr->validator = validate_attribute; zend_ce_return_type_will_change_attribute = register_class_ReturnTypeWillChange(); zend_mark_internal_attribute(zend_ce_return_type_will_change_attribute); diff --git a/Zend/zend_attributes.stub.php b/Zend/zend_attributes.stub.php index fe70de83e4d..242b7511608 100644 --- a/Zend/zend_attributes.stub.php +++ b/Zend/zend_attributes.stub.php @@ -68,7 +68,7 @@ final class SensitiveParameterValue /** * @strict-properties */ -#[Attribute(Attribute::TARGET_METHOD)] +#[Attribute(Attribute::TARGET_METHOD|Attribute::TARGET_PROPERTY)] final class Override { public function __construct() {} diff --git a/Zend/zend_attributes_arginfo.h b/Zend/zend_attributes_arginfo.h index 14afe40c01a..5e7f581dd22 100644 --- a/Zend/zend_attributes_arginfo.h +++ b/Zend/zend_attributes_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 9aee3d8f2ced376f5929048444eaa2529ff90311 */ + * Stub hash: 715016d1ff1b0a6abb325a71083eff397a080c44 */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Attribute___construct, 0, 0, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, flags, IS_LONG, 0, "Attribute::TARGET_ALL") @@ -156,9 +156,7 @@ static zend_class_entry *register_class_Attribute(void) zend_string *attribute_name_Attribute_class_Attribute_0 = zend_string_init_interned("Attribute", sizeof("Attribute") - 1, 1); zend_attribute *attribute_Attribute_class_Attribute_0 = zend_add_class_attribute(class_entry, attribute_name_Attribute_class_Attribute_0, 1); zend_string_release(attribute_name_Attribute_class_Attribute_0); - zval attribute_Attribute_class_Attribute_0_arg0; - ZVAL_LONG(&attribute_Attribute_class_Attribute_0_arg0, ZEND_ATTRIBUTE_TARGET_CLASS); - ZVAL_COPY_VALUE(&attribute_Attribute_class_Attribute_0->args[0].value, &attribute_Attribute_class_Attribute_0_arg0); + ZVAL_LONG(&attribute_Attribute_class_Attribute_0->args[0].value, ZEND_ATTRIBUTE_TARGET_CLASS); return class_entry; } @@ -173,9 +171,7 @@ static zend_class_entry *register_class_ReturnTypeWillChange(void) zend_string *attribute_name_Attribute_class_ReturnTypeWillChange_0 = zend_string_init_interned("Attribute", sizeof("Attribute") - 1, 1); zend_attribute *attribute_Attribute_class_ReturnTypeWillChange_0 = zend_add_class_attribute(class_entry, attribute_name_Attribute_class_ReturnTypeWillChange_0, 1); zend_string_release(attribute_name_Attribute_class_ReturnTypeWillChange_0); - zval attribute_Attribute_class_ReturnTypeWillChange_0_arg0; - ZVAL_LONG(&attribute_Attribute_class_ReturnTypeWillChange_0_arg0, ZEND_ATTRIBUTE_TARGET_METHOD); - ZVAL_COPY_VALUE(&attribute_Attribute_class_ReturnTypeWillChange_0->args[0].value, &attribute_Attribute_class_ReturnTypeWillChange_0_arg0); + ZVAL_LONG(&attribute_Attribute_class_ReturnTypeWillChange_0->args[0].value, ZEND_ATTRIBUTE_TARGET_METHOD); return class_entry; } @@ -190,9 +186,7 @@ static zend_class_entry *register_class_AllowDynamicProperties(void) zend_string *attribute_name_Attribute_class_AllowDynamicProperties_0 = zend_string_init_interned("Attribute", sizeof("Attribute") - 1, 1); zend_attribute *attribute_Attribute_class_AllowDynamicProperties_0 = zend_add_class_attribute(class_entry, attribute_name_Attribute_class_AllowDynamicProperties_0, 1); zend_string_release(attribute_name_Attribute_class_AllowDynamicProperties_0); - zval attribute_Attribute_class_AllowDynamicProperties_0_arg0; - ZVAL_LONG(&attribute_Attribute_class_AllowDynamicProperties_0_arg0, ZEND_ATTRIBUTE_TARGET_CLASS); - ZVAL_COPY_VALUE(&attribute_Attribute_class_AllowDynamicProperties_0->args[0].value, &attribute_Attribute_class_AllowDynamicProperties_0_arg0); + ZVAL_LONG(&attribute_Attribute_class_AllowDynamicProperties_0->args[0].value, ZEND_ATTRIBUTE_TARGET_CLASS); return class_entry; } @@ -207,9 +201,7 @@ static zend_class_entry *register_class_SensitiveParameter(void) zend_string *attribute_name_Attribute_class_SensitiveParameter_0 = zend_string_init_interned("Attribute", sizeof("Attribute") - 1, 1); zend_attribute *attribute_Attribute_class_SensitiveParameter_0 = zend_add_class_attribute(class_entry, attribute_name_Attribute_class_SensitiveParameter_0, 1); zend_string_release(attribute_name_Attribute_class_SensitiveParameter_0); - zval attribute_Attribute_class_SensitiveParameter_0_arg0; - ZVAL_LONG(&attribute_Attribute_class_SensitiveParameter_0_arg0, ZEND_ATTRIBUTE_TARGET_PARAMETER); - ZVAL_COPY_VALUE(&attribute_Attribute_class_SensitiveParameter_0->args[0].value, &attribute_Attribute_class_SensitiveParameter_0_arg0); + ZVAL_LONG(&attribute_Attribute_class_SensitiveParameter_0->args[0].value, ZEND_ATTRIBUTE_TARGET_PARAMETER); return class_entry; } @@ -238,9 +230,7 @@ static zend_class_entry *register_class_Override(void) zend_string *attribute_name_Attribute_class_Override_0 = zend_string_init_interned("Attribute", sizeof("Attribute") - 1, 1); zend_attribute *attribute_Attribute_class_Override_0 = zend_add_class_attribute(class_entry, attribute_name_Attribute_class_Override_0, 1); zend_string_release(attribute_name_Attribute_class_Override_0); - zval attribute_Attribute_class_Override_0_arg0; - ZVAL_LONG(&attribute_Attribute_class_Override_0_arg0, ZEND_ATTRIBUTE_TARGET_METHOD); - ZVAL_COPY_VALUE(&attribute_Attribute_class_Override_0->args[0].value, &attribute_Attribute_class_Override_0_arg0); + ZVAL_LONG(&attribute_Attribute_class_Override_0->args[0].value, ZEND_ATTRIBUTE_TARGET_METHOD | ZEND_ATTRIBUTE_TARGET_PROPERTY); return class_entry; } @@ -263,9 +253,7 @@ static zend_class_entry *register_class_Deprecated(void) zend_string *attribute_name_Attribute_class_Deprecated_0 = zend_string_init_interned("Attribute", sizeof("Attribute") - 1, 1); zend_attribute *attribute_Attribute_class_Deprecated_0 = zend_add_class_attribute(class_entry, attribute_name_Attribute_class_Deprecated_0, 1); zend_string_release(attribute_name_Attribute_class_Deprecated_0); - zval attribute_Attribute_class_Deprecated_0_arg0; - ZVAL_LONG(&attribute_Attribute_class_Deprecated_0_arg0, ZEND_ATTRIBUTE_TARGET_METHOD | ZEND_ATTRIBUTE_TARGET_FUNCTION | ZEND_ATTRIBUTE_TARGET_CLASS_CONST | ZEND_ATTRIBUTE_TARGET_CONST); - ZVAL_COPY_VALUE(&attribute_Attribute_class_Deprecated_0->args[0].value, &attribute_Attribute_class_Deprecated_0_arg0); + ZVAL_LONG(&attribute_Attribute_class_Deprecated_0->args[0].value, ZEND_ATTRIBUTE_TARGET_METHOD | ZEND_ATTRIBUTE_TARGET_FUNCTION | ZEND_ATTRIBUTE_TARGET_CLASS_CONST | ZEND_ATTRIBUTE_TARGET_CONST); return class_entry; } @@ -284,9 +272,7 @@ static zend_class_entry *register_class_NoDiscard(void) zend_string *attribute_name_Attribute_class_NoDiscard_0 = zend_string_init_interned("Attribute", sizeof("Attribute") - 1, 1); zend_attribute *attribute_Attribute_class_NoDiscard_0 = zend_add_class_attribute(class_entry, attribute_name_Attribute_class_NoDiscard_0, 1); zend_string_release(attribute_name_Attribute_class_NoDiscard_0); - zval attribute_Attribute_class_NoDiscard_0_arg0; - ZVAL_LONG(&attribute_Attribute_class_NoDiscard_0_arg0, ZEND_ATTRIBUTE_TARGET_METHOD | ZEND_ATTRIBUTE_TARGET_FUNCTION); - ZVAL_COPY_VALUE(&attribute_Attribute_class_NoDiscard_0->args[0].value, &attribute_Attribute_class_NoDiscard_0_arg0); + ZVAL_LONG(&attribute_Attribute_class_NoDiscard_0->args[0].value, ZEND_ATTRIBUTE_TARGET_METHOD | ZEND_ATTRIBUTE_TARGET_FUNCTION); return class_entry; } diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c index 256f08e05d6..b25925b89f7 100644 --- a/Zend/zend_builtin_functions.c +++ b/Zend/zend_builtin_functions.c @@ -72,9 +72,12 @@ zend_result zend_startup_builtin_functions(void) /* {{{ */ ZEND_FUNCTION(clone) { zend_object *zobj; + HashTable *with = (HashTable*)&zend_empty_array; - ZEND_PARSE_PARAMETERS_START(1, 1) + ZEND_PARSE_PARAMETERS_START(1, 2) Z_PARAM_OBJ(zobj) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_HT(with) ZEND_PARSE_PARAMETERS_END(); /* clone() also exists as the ZEND_CLONE OPcode and both implementations must be kept in sync. */ @@ -95,7 +98,16 @@ ZEND_FUNCTION(clone) } zend_object *cloned; - cloned = zobj->handlers->clone_obj(zobj); + if (zend_hash_num_elements(with) > 0) { + if (UNEXPECTED(!zobj->handlers->clone_obj_with)) { + zend_throw_error(NULL, "Cloning objects of class %s with updated properties is not supported", ZSTR_VAL(ce->name)); + RETURN_THROWS(); + } + + cloned = zobj->handlers->clone_obj_with(zobj, scope, with); + } else { + cloned = zobj->handlers->clone_obj(zobj); + } ZEND_ASSERT(cloned || EG(exception)); if (EXPECTED(cloned)) { @@ -1471,15 +1483,15 @@ ZEND_FUNCTION(get_defined_functions) zval internal, user; zend_string *key; zend_function *func; - bool exclude_disabled = 1; + bool exclude_disabled = true; if (zend_parse_parameters(ZEND_NUM_ARGS(), "|b", &exclude_disabled) == FAILURE) { RETURN_THROWS(); } - if (exclude_disabled == 0) { + if (ZEND_NUM_ARGS() == 1) { zend_error(E_DEPRECATED, - "get_defined_functions(): Setting $exclude_disabled to false has no effect"); + "get_defined_functions(): The $exclude_disabled parameter has no effect since PHP 8.0"); } array_init(&internal); diff --git a/Zend/zend_builtin_functions.stub.php b/Zend/zend_builtin_functions.stub.php index 256c405c71c..9b2267b531e 100644 --- a/Zend/zend_builtin_functions.stub.php +++ b/Zend/zend_builtin_functions.stub.php @@ -8,7 +8,7 @@ class stdClass } /** @refcount 1 */ -function _clone(object $object): object {} +function clone(object $object, array $withProperties = []): object {} function exit(string|int $status = 0): never {} diff --git a/Zend/zend_builtin_functions_arginfo.h b/Zend/zend_builtin_functions_arginfo.h index 1c595ecd577..cf349b551ac 100644 --- a/Zend/zend_builtin_functions_arginfo.h +++ b/Zend/zend_builtin_functions_arginfo.h @@ -1,8 +1,9 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 12327caa3fe940ccef68ed99f9278982dc0173a5 */ + * Stub hash: 9b49f527064695c812cd204d9efc63c13681d942 */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_clone, 0, 1, IS_OBJECT, 0) ZEND_ARG_TYPE_INFO(0, object, IS_OBJECT, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, withProperties, IS_ARRAY, 0, "[]") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_exit, 0, 0, IS_NEVER, 0) diff --git a/Zend/zend_closures.c b/Zend/zend_closures.c index 5777e1a34a2..bdcdc329647 100644 --- a/Zend/zend_closures.c +++ b/Zend/zend_closures.c @@ -418,6 +418,23 @@ ZEND_METHOD(Closure, fromCallable) } /* }}} */ +ZEND_METHOD(Closure, getCurrent) +{ + ZEND_PARSE_PARAMETERS_NONE(); + + zend_execute_data *prev_ex = EX(prev_execute_data); + + if (!prev_ex + || !prev_ex->func + || (prev_ex->func->common.fn_flags & (ZEND_ACC_CLOSURE|ZEND_ACC_FAKE_CLOSURE)) != ZEND_ACC_CLOSURE) { + zend_throw_error(NULL, "Current function is not a closure"); + RETURN_THROWS(); + } + + zend_object *obj = ZEND_CLOSURE_OBJECT(prev_ex->func); + RETURN_OBJ_COPY(obj); +} + static ZEND_COLD zend_function *zend_closure_get_constructor(zend_object *object) /* {{{ */ { zend_throw_error(NULL, "Instantiation of class Closure is not allowed"); diff --git a/Zend/zend_closures.stub.php b/Zend/zend_closures.stub.php index daa92492b18..46b51617eef 100644 --- a/Zend/zend_closures.stub.php +++ b/Zend/zend_closures.stub.php @@ -21,4 +21,6 @@ final class Closure public function call(object $newThis, mixed ...$args): mixed {} public static function fromCallable(callable $callback): Closure {} + + public static function getCurrent(): Closure {} } diff --git a/Zend/zend_closures_arginfo.h b/Zend/zend_closures_arginfo.h index 57066078a88..4ce02c40e55 100644 --- a/Zend/zend_closures_arginfo.h +++ b/Zend/zend_closures_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: e3b480674671a698814db282c5ea34d438fe519d */ + * Stub hash: e0626e52adb2d38dad1140c1a28cc7774cc84500 */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Closure___construct, 0, 0, 0) ZEND_END_ARG_INFO() @@ -24,11 +24,15 @@ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_Closure_fromCallable, 0, 1, ZEND_ARG_TYPE_INFO(0, callback, IS_CALLABLE, 0) ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_Closure_getCurrent, 0, 0, Closure, 0) +ZEND_END_ARG_INFO() + ZEND_METHOD(Closure, __construct); ZEND_METHOD(Closure, bind); ZEND_METHOD(Closure, bindTo); ZEND_METHOD(Closure, call); ZEND_METHOD(Closure, fromCallable); +ZEND_METHOD(Closure, getCurrent); static const zend_function_entry class_Closure_methods[] = { ZEND_ME(Closure, __construct, arginfo_class_Closure___construct, ZEND_ACC_PRIVATE) @@ -36,6 +40,7 @@ static const zend_function_entry class_Closure_methods[] = { ZEND_ME(Closure, bindTo, arginfo_class_Closure_bindTo, ZEND_ACC_PUBLIC) ZEND_ME(Closure, call, arginfo_class_Closure_call, ZEND_ACC_PUBLIC) ZEND_ME(Closure, fromCallable, arginfo_class_Closure_fromCallable, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) + ZEND_ME(Closure, getCurrent, arginfo_class_Closure_getCurrent, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) ZEND_FE_END }; diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 8e03773246b..7f4299ff9a8 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -821,7 +821,8 @@ static void zend_do_free(znode *op1) /* {{{ */ } else { while (opline >= CG(active_op_array)->opcodes) { if ((opline->opcode == ZEND_FETCH_LIST_R || - opline->opcode == ZEND_FETCH_LIST_W) && + opline->opcode == ZEND_FETCH_LIST_W || + opline->opcode == ZEND_EXT_STMT) && opline->op1_type == IS_VAR && opline->op1.var == op1->u.op.var) { zend_emit_op(NULL, ZEND_FREE, op1, NULL); @@ -1327,7 +1328,6 @@ ZEND_API zend_class_entry *zend_bind_class_in_slot( ce = zend_do_link_class(ce, lc_parent_name, Z_STR_P(lcname)); if (ce) { - ZEND_ASSERT(!EG(exception)); zend_observer_class_linked_notify(ce, Z_STR_P(lcname)); return ce; } @@ -1394,7 +1394,6 @@ static zend_string *resolve_class_name(zend_string *name, zend_class_entry *scop * null byte here, to avoid larger parts of the type being omitted by printing code later. */ size_t len = strlen(ZSTR_VAL(name)); if (len != ZSTR_LEN(name)) { - ZEND_ASSERT(scope && "This should only happen with resolved types"); return zend_string_init(ZSTR_VAL(name), len, 0); } return zend_string_copy(name); @@ -1922,7 +1921,7 @@ static void zend_add_to_list(void *result, void *item) /* {{{ */ } /* }}} */ -static void zend_do_extended_stmt(void) /* {{{ */ +static void zend_do_extended_stmt(znode* result) /* {{{ */ { zend_op *opline; @@ -1933,6 +1932,9 @@ static void zend_do_extended_stmt(void) /* {{{ */ opline = get_next_op(); opline->opcode = ZEND_EXT_STMT; + if (result) { + SET_NODE(opline->op1, result); + } } /* }}} */ @@ -2724,7 +2726,8 @@ static inline bool zend_is_call(zend_ast *ast) /* {{{ */ return ast->kind == ZEND_AST_CALL || ast->kind == ZEND_AST_METHOD_CALL || ast->kind == ZEND_AST_NULLSAFE_METHOD_CALL - || ast->kind == ZEND_AST_STATIC_CALL; + || ast->kind == ZEND_AST_STATIC_CALL + || ast->kind == ZEND_AST_PIPE; } /* }}} */ @@ -4144,17 +4147,19 @@ static zend_result zend_compile_func_defined(znode *result, zend_ast_list *args) } /* }}} */ -static zend_result zend_compile_func_chr(znode *result, zend_ast_list *args) /* {{{ */ +static zend_result zend_compile_func_chr(znode *result, const zend_ast_list *args) /* {{{ */ { - - if (args->children == 1 && - args->child[0]->kind == ZEND_AST_ZVAL && - Z_TYPE_P(zend_ast_get_zval(args->child[0])) == IS_LONG) { - - zend_long c = Z_LVAL_P(zend_ast_get_zval(args->child[0])) & 0xff; - + zval *zint; + if ( + args->children == 1 + && args->child[0]->kind == ZEND_AST_ZVAL + && (zint = zend_ast_get_zval(args->child[0])) + && Z_TYPE_P(zint) == IS_LONG + && Z_LVAL_P(zint) >= 0 + && Z_LVAL_P(zint) <= 255 + ) { result->op_type = IS_CONST; - ZVAL_CHAR(&result->u.constant, c); + ZVAL_CHAR(&result->u.constant, Z_LVAL_P(zint)); return SUCCESS; } else { return FAILURE; @@ -5701,8 +5706,20 @@ static void zend_compile_return(zend_ast *ast) /* {{{ */ expr_ast ? &expr_node : NULL, CG(active_op_array)->arg_info - 1, 0); } + uint32_t opnum_before_finally = get_next_op_number(); + zend_handle_loops_and_finally((expr_node.op_type & (IS_TMP_VAR | IS_VAR)) ? &expr_node : NULL); + /* Content of reference might have changed in finally, repeat type check. */ + if (by_ref + /* Check if any opcodes were emitted since the last return type check. */ + && opnum_before_finally != get_next_op_number() + && !is_generator + && (CG(active_op_array)->fn_flags & ZEND_ACC_HAS_RETURN_TYPE)) { + zend_emit_return_type_check( + expr_ast ? &expr_node : NULL, CG(active_op_array)->arg_info - 1, 0); + } + opline = zend_emit_op(NULL, by_ref ? ZEND_RETURN_BY_REF : ZEND_RETURN, &expr_node, NULL); @@ -6040,7 +6057,7 @@ static void zend_compile_for(zend_ast *ast) /* {{{ */ zend_update_jump_target_to_next(opnum_jmp); zend_compile_for_expr_list(&result, cond_ast); - zend_do_extended_stmt(); + zend_do_extended_stmt(NULL); zend_emit_cond_jump(ZEND_JMPNZ, &result, opnum_start); @@ -6161,7 +6178,7 @@ static void zend_compile_if(zend_ast *ast) /* {{{ */ if (i > 0) { CG(zend_lineno) = cond_ast->lineno; - zend_do_extended_stmt(); + zend_do_extended_stmt(NULL); } zend_compile_expr(&cond_node, cond_ast); @@ -6303,6 +6320,11 @@ static void zend_compile_switch(zend_ast *ast) /* {{{ */ continue; } + if (case_ast->attr == ZEND_ALT_CASE_SYNTAX) { + CG(zend_lineno) = case_ast->lineno; + zend_error(E_DEPRECATED, "Case statements followed by a semicolon (;) are deprecated, use a colon (:) instead"); + } + zend_compile_expr(&cond_node, cond_ast); if (expr_node.op_type == IS_CONST @@ -6490,6 +6512,8 @@ static void zend_compile_pipe(znode *result, zend_ast *ast) } zend_compile_expr(result, fcall_ast); + CG(zend_lineno) = fcall_ast->lineno; + zend_do_extended_stmt(result); } static void zend_compile_match(znode *result, zend_ast *ast) @@ -7897,6 +7921,11 @@ static void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast, uint32 if (attributes_ast) { zend_compile_attributes( &prop->attributes, attributes_ast, 0, ZEND_ATTRIBUTE_TARGET_PROPERTY, ZEND_ATTRIBUTE_TARGET_PARAMETER); + + zend_attribute *override_attribute = zend_get_attribute_str(prop->attributes, "override", sizeof("override")-1); + if (override_attribute) { + prop->flags |= ZEND_ACC_OVERRIDE; + } } } } @@ -7921,6 +7950,8 @@ static void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast, uint32 continue; } + CG(zend_lineno) = param_ast->lineno; + /* Emit $this->prop = $prop for promoted properties. */ zend_string *name = zend_ast_get_str(param_ast->child[1]); znode name_node, value_node; @@ -8520,7 +8551,7 @@ static zend_op_array *zend_compile_func_decl_ex( /* put the implicit return on the really last line */ CG(zend_lineno) = decl->end_lineno; - zend_do_extended_stmt(); + zend_do_extended_stmt(NULL); zend_emit_final_return(0); pass_two(CG(active_op_array)); @@ -8874,6 +8905,11 @@ static void zend_compile_prop_decl(zend_ast *ast, zend_ast *type_ast, uint32_t f if (attr_ast) { zend_compile_attributes(&info->attributes, attr_ast, 0, ZEND_ATTRIBUTE_TARGET_PROPERTY, 0); + + zend_attribute *override_attribute = zend_get_attribute_str(info->attributes, "override", sizeof("override")-1); + if (override_attribute) { + info->flags |= ZEND_ACC_OVERRIDE; + } } CG(context).active_property_info_name = old_active_property_info_name; @@ -9719,7 +9755,11 @@ static void zend_compile_halt_compiler(zend_ast *ast) /* {{{ */ name = zend_mangle_property_name(const_name, sizeof(const_name) - 1, ZSTR_VAL(filename), ZSTR_LEN(filename), 0); - zend_register_long_constant(ZSTR_VAL(name), ZSTR_LEN(name), offset, 0, 0); + /* Avoid repeated declaration of the __COMPILER_HALT_OFFSET__ constant in + * case this file was already included. */ + if (!zend_hash_find(EG(zend_constants), name)) { + zend_register_long_constant(ZSTR_VAL(name), ZSTR_LEN(name), offset, 0, 0); + } zend_string_release_ex(name, 0); } /* }}} */ @@ -10824,6 +10864,8 @@ static void zend_compile_shell_exec(znode *result, zend_ast *ast) /* {{{ */ zval fn_name; zend_ast *name_ast, *args_ast, *call_ast; + zend_error(E_DEPRECATED, "The backtick (`) operator is deprecated, use shell_exec() instead"); + ZVAL_STRING(&fn_name, "shell_exec"); name_ast = zend_ast_create_zval(&fn_name); args_ast = zend_ast_create_list(1, ZEND_AST_ARG_LIST, expr_ast); @@ -11590,7 +11632,7 @@ static void zend_compile_stmt(zend_ast *ast) /* {{{ */ CG(zend_lineno) = ast->lineno; if ((CG(compiler_options) & ZEND_COMPILE_EXTENDED_STMT) && !zend_is_unticked_stmt(ast)) { - zend_do_extended_stmt(); + zend_do_extended_stmt(NULL); } switch (ast->kind) { diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index 7ac0a2b8b2c..84afd443419 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -24,6 +24,7 @@ #include "zend_types.h" #include "zend_map_ptr.h" #include "zend_alloc.h" +#include "zend_vm_opcodes.h" #include #include @@ -96,7 +97,7 @@ typedef struct _zend_ast_znode { znode node; } zend_ast_znode; -ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_znode(znode *node); +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_znode(const znode *node); static zend_always_inline znode *zend_ast_get_znode(zend_ast *ast) { return &((zend_ast_znode *) ast)->node; @@ -135,7 +136,7 @@ void zend_const_expr_to_zval(zval *result, zend_ast **ast_ptr, bool allow_dynami typedef int (*user_opcode_handler_t) (zend_execute_data *execute_data); struct _zend_op { - const void *handler; + zend_vm_opcode_handler_t handler; znode_op op1; znode_op op2; znode_op result; @@ -251,9 +252,12 @@ typedef struct _zend_oparray_context { /* Flag to differentiate cases from constants. | | | */ /* Must not conflict with ZEND_ACC_ visibility flags | | | */ /* or IS_CONSTANT_VISITED_MARK | | | */ -#define ZEND_CLASS_CONST_IS_CASE (1 << 6) /* | | | X */ +#define ZEND_CLASS_CONST_IS_CASE (1 << 6) /* | | | X */ /* | | | */ -/* Property Flags (unused: 13...) | | | */ +/* has #[\Override] attribute | | | */ +#define ZEND_ACC_OVERRIDE (1 << 28) /* | X | X | */ +/* | | | */ +/* Property Flags (unused: 13-27,29...) | | | */ /* =========== | | | */ /* | | | */ /* Promoted property / parameter | | | */ @@ -392,9 +396,6 @@ typedef struct _zend_oparray_context { /* supports opcache compile-time evaluation (funcs) | | | */ #define ZEND_ACC_COMPILE_TIME_EVAL (1 << 27) /* | X | | */ /* | | | */ -/* has #[\Override] attribute | | | */ -#define ZEND_ACC_OVERRIDE (1 << 28) /* | X | | */ -/* | | | */ /* Has IS_PTR operands that needs special cleaning; same | | | */ /* value as ZEND_ACC_OVERRIDE but override is for class | | | */ /* methods and this is for the top level op array | | | */ @@ -1126,6 +1127,7 @@ ZEND_API zend_string *zend_type_to_string(zend_type type); ((ZEND_TYPE_FULL_MASK((arg_info)->type) & _ZEND_IS_TENTATIVE_BIT) != 0) #define ZEND_DIM_IS (1 << 0) /* isset fetch needed for null coalesce. Set in zend_compile.c for ZEND_AST_DIM nested within ZEND_AST_COALESCE. */ +#define ZEND_ALT_CASE_SYNTAX (1 << 1) /* deprecated switch case terminated by semicolon */ /* Attributes for ${} encaps var in strings (ZEND_AST_DIM or ZEND_AST_VAR node) */ /* ZEND_AST_VAR nodes can have any of the ZEND_ENCAPS_VAR_* flags */ diff --git a/Zend/zend_constants_arginfo.h b/Zend/zend_constants_arginfo.h index 3edb91265f4..04ccc3025f1 100644 --- a/Zend/zend_constants_arginfo.h +++ b/Zend/zend_constants_arginfo.h @@ -31,9 +31,7 @@ static void register_zend_constants_symbols(int module_number) zend_attribute *attribute_Deprecated_const_E_STRICT_0 = zend_add_global_constant_attribute(const_E_STRICT, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_const_E_STRICT_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_4)); attribute_Deprecated_const_E_STRICT_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_const_E_STRICT_0_arg1; zend_string *attribute_Deprecated_const_E_STRICT_0_arg1_str = zend_string_init("the error level was removed", strlen("the error level was removed"), 1); - ZVAL_STR(&attribute_Deprecated_const_E_STRICT_0_arg1, attribute_Deprecated_const_E_STRICT_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_const_E_STRICT_0->args[1].value, &attribute_Deprecated_const_E_STRICT_0_arg1); + ZVAL_STR(&attribute_Deprecated_const_E_STRICT_0->args[1].value, attribute_Deprecated_const_E_STRICT_0_arg1_str); attribute_Deprecated_const_E_STRICT_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); } diff --git a/Zend/zend_exceptions.c b/Zend/zend_exceptions.c index 99c4a48a948..0b0945aac0f 100644 --- a/Zend/zend_exceptions.c +++ b/Zend/zend_exceptions.c @@ -67,7 +67,7 @@ static int zend_implement_throwable(zend_class_entry *interface, zend_class_entr { /* zend_ce_exception and zend_ce_error may not be initialized yet when this is called (e.g when * implementing Throwable for Exception itself). Perform a manual inheritance check. */ - zend_class_entry *root = class_type; + const zend_class_entry *root = class_type; while (root->parent) { root = root->parent; } @@ -89,13 +89,13 @@ static int zend_implement_throwable(zend_class_entry *interface, zend_class_entr } /* }}} */ -static inline zend_class_entry *i_get_exception_base(zend_object *object) /* {{{ */ +static inline zend_class_entry *i_get_exception_base(const zend_object *object) /* {{{ */ { return instanceof_function(object->ce, zend_ce_exception) ? zend_ce_exception : zend_ce_error; } /* }}} */ -ZEND_API zend_class_entry *zend_get_exception_base(zend_object *object) /* {{{ */ +ZEND_API zend_class_entry *zend_get_exception_base(const zend_object *object) /* {{{ */ { return i_get_exception_base(object); } @@ -192,7 +192,7 @@ ZEND_API ZEND_COLD void zend_throw_exception_internal(zend_object *exception) /* #endif /* HAVE_DTRACE */ if (exception != NULL) { - zend_object *previous = EG(exception); + const zend_object *previous = EG(exception); if (previous && zend_is_unwind_exit(previous)) { /* Don't replace unwinding exception with different exception. */ OBJ_RELEASE(exception); @@ -695,16 +695,33 @@ ZEND_METHOD(Exception, __toString) zval trace, *exception; zend_class_entry *base_ce; zend_string *str; - zend_fcall_info fci; zval rv, tmp; - zend_string *fname; ZEND_PARSE_PARAMETERS_NONE(); str = ZSTR_EMPTY_ALLOC(); exception = ZEND_THIS; - fname = ZSTR_INIT_LITERAL("gettraceasstring", 0); + base_ce = i_get_exception_base(Z_OBJ_P(exception)); + + /* As getTraceAsString method is final we can grab it once */ + zend_function *getTraceAsString = zend_hash_str_find_ptr(&base_ce->function_table, ZEND_STRL("gettraceasstring")); + ZEND_ASSERT(getTraceAsString && "Method getTraceAsString must exist"); + + + zend_fcall_info fci; + fci.size = sizeof(fci); + ZVAL_UNDEF(&fci.function_name); + fci.retval = &trace; + fci.param_count = 0; + fci.params = NULL; + fci.object = NULL; + fci.named_params = NULL; + + zend_fcall_info_cache fcc; + fcc.function_handler = getTraceAsString; + fcc.called_scope = base_ce; + fcc.closure = NULL; while (exception && Z_TYPE_P(exception) == IS_OBJECT && instanceof_function(Z_OBJCE_P(exception), zend_ce_throwable)) { zend_string *prev_str = str; @@ -712,15 +729,9 @@ ZEND_METHOD(Exception, __toString) zend_string *file = zval_get_string(GET_PROPERTY(exception, ZEND_STR_FILE)); zend_long line = zval_get_long(GET_PROPERTY(exception, ZEND_STR_LINE)); - fci.size = sizeof(fci); - ZVAL_STR(&fci.function_name, fname); - fci.object = Z_OBJ_P(exception); - fci.retval = &trace; - fci.param_count = 0; - fci.params = NULL; - fci.named_params = NULL; - - zend_call_function(&fci, NULL); + fcc.object = Z_OBJ_P(exception); + fcc.calling_scope = Z_OBJCE_P(exception); + zend_call_function(&fci, &fcc); if (Z_TYPE(trace) != IS_STRING) { zval_ptr_dtor(&trace); @@ -765,11 +776,11 @@ ZEND_METHOD(Exception, __toString) break; } } - zend_string_release_ex(fname, 0); exception = ZEND_THIS; /* Reset apply counts */ - while (Z_TYPE_P(exception) == IS_OBJECT && (base_ce = i_get_exception_base(Z_OBJ_P(exception))) && instanceof_function(Z_OBJCE_P(exception), base_ce)) { + zend_class_entry *previous_base_ce; + while (Z_TYPE_P(exception) == IS_OBJECT && (previous_base_ce = i_get_exception_base(Z_OBJ_P(exception))) && instanceof_function(Z_OBJCE_P(exception), previous_base_ce)) { if (Z_IS_RECURSIVE_P(exception)) { Z_UNPROTECT_RECURSION_P(exception); } else { @@ -779,13 +790,10 @@ ZEND_METHOD(Exception, __toString) ZVAL_DEREF(exception); } - exception = ZEND_THIS; - base_ce = i_get_exception_base(Z_OBJ_P(exception)); - /* We store the result in the private property string so we can access * the result in uncaught exception handlers without memleaks. */ ZVAL_STR(&tmp, str); - zend_update_property_ex(base_ce, Z_OBJ_P(exception), ZSTR_KNOWN(ZEND_STR_STRING), &tmp); + zend_update_property_ex(base_ce, Z_OBJ_P(ZEND_THIS), ZSTR_KNOWN(ZEND_STR_STRING), &tmp); RETURN_STR(str); } diff --git a/Zend/zend_exceptions.h b/Zend/zend_exceptions.h index 5df49dcd6a3..24d9f4efd80 100644 --- a/Zend/zend_exceptions.h +++ b/Zend/zend_exceptions.h @@ -48,7 +48,7 @@ ZEND_API ZEND_COLD void zend_throw_exception_internal(zend_object *exception); void zend_register_default_exception(void); -ZEND_API zend_class_entry *zend_get_exception_base(zend_object *object); +ZEND_API zend_class_entry *zend_get_exception_base(const zend_object *object); ZEND_API void zend_register_default_classes(void); diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 734494d252d..3908299a41c 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -5211,7 +5211,7 @@ static zend_never_inline zend_op_array* ZEND_FASTCALL zend_include_or_eval(zval } } else if (UNEXPECTED(EG(exception))) { break; - } else if (UNEXPECTED(strlen(ZSTR_VAL(inc_filename)) != ZSTR_LEN(inc_filename))) { + } else if (UNEXPECTED(zend_str_has_nul_byte(inc_filename))) { zend_message_dispatcher( (type == ZEND_INCLUDE_ONCE) ? ZMSG_FAILED_INCLUDE_FOPEN : ZMSG_FAILED_REQUIRE_FOPEN, @@ -5245,7 +5245,7 @@ static zend_never_inline zend_op_array* ZEND_FASTCALL zend_include_or_eval(zval break; case ZEND_INCLUDE: case ZEND_REQUIRE: - if (UNEXPECTED(strlen(ZSTR_VAL(inc_filename)) != ZSTR_LEN(inc_filename))) { + if (UNEXPECTED(zend_str_has_nul_byte(inc_filename))) { zend_message_dispatcher( (type == ZEND_INCLUDE) ? ZMSG_FAILED_INCLUDE_FOPEN : ZMSG_FAILED_REQUIRE_FOPEN, diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 6d2a6195cd5..06618b3a9de 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -1130,22 +1130,20 @@ ZEND_API zend_result zend_call_method_if_exists( zend_object *object, zend_string *method_name, zval *retval, uint32_t param_count, zval *params) { - zend_fcall_info fci; - fci.size = sizeof(zend_fcall_info); - fci.object = object; - ZVAL_STR(&fci.function_name, method_name); - fci.retval = retval; - fci.param_count = param_count; - fci.params = params; - fci.named_params = NULL; - + zval zval_method; zend_fcall_info_cache fcc; - if (!zend_is_callable_ex(&fci.function_name, fci.object, IS_CALLABLE_SUPPRESS_DEPRECATIONS, NULL, &fcc, NULL)) { + + ZVAL_STR(&zval_method, method_name); + + if (UNEXPECTED(!zend_is_callable_ex(&zval_method, object, IS_CALLABLE_SUPPRESS_DEPRECATIONS, NULL, &fcc, NULL))) { ZVAL_UNDEF(retval); return FAILURE; } - return zend_call_function(&fci, &fcc); + zend_call_known_fcc(&fcc, retval, param_count, params, NULL); + /* Need to free potential trampoline (__call/__callStatic) copied function handler before releasing the closure */ + zend_release_fcall_info_cache(&fcc); + return SUCCESS; } /* 0-9 a-z A-Z _ \ 0x80-0xff */ diff --git a/Zend/zend_generators.c b/Zend/zend_generators.c index a6ea91a7425..22f6048040b 100644 --- a/Zend/zend_generators.c +++ b/Zend/zend_generators.c @@ -498,8 +498,14 @@ ZEND_API zend_execute_data *zend_generator_check_placeholder_frame(zend_execute_ return ptr; } -static void zend_generator_throw_exception(zend_generator *generator, zval *exception) +static zend_result zend_generator_throw_exception(zend_generator *generator, zval *exception) { + if (generator->flags & ZEND_GENERATOR_CURRENTLY_RUNNING) { + zval_ptr_dtor(exception); + zend_throw_error(NULL, "Cannot resume an already running generator"); + return FAILURE; + } + zend_execute_data *original_execute_data = EG(current_execute_data); /* Throw the exception in the context of the generator. Decrementing the opline @@ -520,6 +526,8 @@ static void zend_generator_throw_exception(zend_generator *generator, zval *exce } EG(current_execute_data) = original_execute_data; + + return SUCCESS; } static void zend_generator_add_child(zend_generator *generator, zend_generator *child) @@ -786,6 +794,8 @@ try_again: orig_generator->execute_fake.prev_execute_data = original_execute_data; } + generator->flags |= ZEND_GENERATOR_CURRENTLY_RUNNING; + /* Ensure this is run after executor_data swap to have a proper stack trace */ if (UNEXPECTED(!Z_ISUNDEF(generator->values))) { if (EXPECTED(zend_generator_get_next_delegated_value(generator) == SUCCESS)) { @@ -794,7 +804,7 @@ try_again: EG(jit_trace_num) = original_jit_trace_num; orig_generator->flags &= ~(ZEND_GENERATOR_DO_INIT | ZEND_GENERATOR_IN_FIBER); - generator->flags &= ~ZEND_GENERATOR_IN_FIBER; + generator->flags &= ~(ZEND_GENERATOR_CURRENTLY_RUNNING | ZEND_GENERATOR_IN_FIBER); return; } /* If there are no more delegated values, resume the generator @@ -817,7 +827,6 @@ try_again: * account for the following increment */ || (generator->flags & ZEND_GENERATOR_FORCED_CLOSE)); generator->execute_data->opline++; - generator->flags |= ZEND_GENERATOR_CURRENTLY_RUNNING; if (!ZEND_OBSERVER_ENABLED) { zend_execute_ex(generator->execute_data); } else { @@ -1025,7 +1034,9 @@ ZEND_METHOD(Generator, throw) if (generator->execute_data) { zend_generator *root = zend_generator_get_current(generator); - zend_generator_throw_exception(root, exception); + if (zend_generator_throw_exception(root, exception) == FAILURE) { + return; + } zend_generator_resume(generator); diff --git a/Zend/zend_globals.h b/Zend/zend_globals.h index b4e94ec1f98..48b978b5350 100644 --- a/Zend/zend_globals.h +++ b/Zend/zend_globals.h @@ -295,7 +295,8 @@ struct _zend_executor_globals { size_t fiber_stack_size; /* If record_errors is enabled, all emitted diagnostics will be recorded, - * in addition to being processed as usual. */ + * and their processing is delayed until zend_emit_recorded_errors() + * is called or a fatal diagnostic is emitted. */ bool record_errors; uint32_t num_errors; zend_error_info **errors; diff --git a/Zend/zend_hash.c b/Zend/zend_hash.c index 66cfb250d1f..f48c298f167 100644 --- a/Zend/zend_hash.c +++ b/Zend/zend_hash.c @@ -1378,7 +1378,7 @@ ZEND_API void ZEND_FASTCALL zend_hash_rehash(HashTable *ht) q->key = p->key; Z_NEXT(q->val) = HT_HASH(ht, nIndex); HT_HASH(ht, nIndex) = HT_IDX_TO_HASH(j); - if (UNEXPECTED(ht->nInternalPointer == i)) { + if (UNEXPECTED(ht->nInternalPointer > j && ht->nInternalPointer <= i)) { ht->nInternalPointer = j; } q++; @@ -1397,7 +1397,7 @@ ZEND_API void ZEND_FASTCALL zend_hash_rehash(HashTable *ht) q->key = p->key; Z_NEXT(q->val) = HT_HASH(ht, nIndex); HT_HASH(ht, nIndex) = HT_IDX_TO_HASH(j); - if (UNEXPECTED(ht->nInternalPointer == i)) { + if (UNEXPECTED(ht->nInternalPointer > j && ht->nInternalPointer <= i)) { ht->nInternalPointer = j; } if (UNEXPECTED(i >= iter_pos)) { @@ -2842,7 +2842,7 @@ ZEND_API zend_result ZEND_FASTCALL zend_hash_move_backwards_ex(const HashTable * /* This function should be made binary safe */ -ZEND_API int ZEND_FASTCALL zend_hash_get_current_key_ex(const HashTable *ht, zend_string **str_index, zend_ulong *num_index, const HashPosition *pos) +ZEND_API zend_hash_key_type ZEND_FASTCALL zend_hash_get_current_key_ex(const HashTable *ht, zend_string **str_index, zend_ulong *num_index, const HashPosition *pos) { uint32_t idx; Bucket *p; @@ -2889,7 +2889,7 @@ ZEND_API void ZEND_FASTCALL zend_hash_get_current_key_zval_ex(const HashTable *h } } -ZEND_API int ZEND_FASTCALL zend_hash_get_current_key_type_ex(const HashTable *ht, const HashPosition *pos) +ZEND_API zend_hash_key_type ZEND_FASTCALL zend_hash_get_current_key_type_ex(const HashTable *ht, const HashPosition *pos) { uint32_t idx; Bucket *p; diff --git a/Zend/zend_hash.h b/Zend/zend_hash.h index b2aaecce0d2..71206e61550 100644 --- a/Zend/zend_hash.h +++ b/Zend/zend_hash.h @@ -26,9 +26,11 @@ #include "zend_string.h" #include "zend_sort.h" -#define HASH_KEY_IS_STRING 1 -#define HASH_KEY_IS_LONG 2 -#define HASH_KEY_NON_EXISTENT 3 +typedef enum { + HASH_KEY_IS_STRING = 1, + HASH_KEY_IS_LONG, + HASH_KEY_NON_EXISTENT +} zend_hash_key_type; #define HASH_UPDATE (1<<0) /* Create new entry, or update the existing one. */ #define HASH_ADD (1<<1) /* Create new entry, or fail if it exists. */ @@ -251,9 +253,9 @@ ZEND_API HashPosition ZEND_FASTCALL zend_hash_get_current_pos(const HashTable *h ZEND_API zend_result ZEND_FASTCALL zend_hash_move_forward_ex(const HashTable *ht, HashPosition *pos); ZEND_API zend_result ZEND_FASTCALL zend_hash_move_backwards_ex(const HashTable *ht, HashPosition *pos); -ZEND_API int ZEND_FASTCALL zend_hash_get_current_key_ex(const HashTable *ht, zend_string **str_index, zend_ulong *num_index, const HashPosition *pos); +ZEND_API zend_hash_key_type ZEND_FASTCALL zend_hash_get_current_key_ex(const HashTable *ht, zend_string **str_index, zend_ulong *num_index, const HashPosition *pos); ZEND_API void ZEND_FASTCALL zend_hash_get_current_key_zval_ex(const HashTable *ht, zval *key, const HashPosition *pos); -ZEND_API int ZEND_FASTCALL zend_hash_get_current_key_type_ex(const HashTable *ht, const HashPosition *pos); +ZEND_API zend_hash_key_type ZEND_FASTCALL zend_hash_get_current_key_type_ex(const HashTable *ht, const HashPosition *pos); ZEND_API zval* ZEND_FASTCALL zend_hash_get_current_data_ex(const HashTable *ht, const HashPosition *pos); ZEND_API void ZEND_FASTCALL zend_hash_internal_pointer_reset_ex(const HashTable *ht, HashPosition *pos); ZEND_API void ZEND_FASTCALL zend_hash_internal_pointer_end_ex(const HashTable *ht, HashPosition *pos); @@ -270,13 +272,13 @@ static zend_always_inline zend_result zend_hash_move_forward(HashTable *ht) { static zend_always_inline zend_result zend_hash_move_backwards(HashTable *ht) { return zend_hash_move_backwards_ex(ht, &ht->nInternalPointer); } -static zend_always_inline int zend_hash_get_current_key(const HashTable *ht, zend_string **str_index, zend_ulong *num_index) { +static zend_always_inline zend_hash_key_type zend_hash_get_current_key(const HashTable *ht, zend_string **str_index, zend_ulong *num_index) { return zend_hash_get_current_key_ex(ht, str_index, num_index, &ht->nInternalPointer); } static zend_always_inline void zend_hash_get_current_key_zval(const HashTable *ht, zval *key) { zend_hash_get_current_key_zval_ex(ht, key, &ht->nInternalPointer); } -static zend_always_inline int zend_hash_get_current_key_type(const HashTable *ht) { +static zend_always_inline zend_hash_key_type zend_hash_get_current_key_type(const HashTable *ht) { return zend_hash_get_current_key_type_ex(ht, &ht->nInternalPointer); } static zend_always_inline zval* zend_hash_get_current_data(const HashTable *ht) { diff --git a/Zend/zend_inheritance.c b/Zend/zend_inheritance.c index d27cca5b761..bbc7a767e1b 100644 --- a/Zend/zend_inheritance.c +++ b/Zend/zend_inheritance.c @@ -1085,10 +1085,7 @@ static void ZEND_COLD emit_incompatible_method_error( "Return type of %s should either be compatible with %s, " "or the #[\\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice", ZSTR_VAL(child_prototype), ZSTR_VAL(parent_prototype)); - if (EG(exception)) { - zend_exception_uncaught_error( - "During inheritance of %s", ZSTR_VAL(parent_scope->name)); - } + ZEND_ASSERT(!EG(exception)); } } else { zend_error_at(E_COMPILE_ERROR, func_filename(child), func_lineno(child), @@ -1566,6 +1563,8 @@ static void do_inherit_property(zend_property_info *parent_info, zend_string *ke ZSTR_VAL(key), ZSTR_VAL(parent_info->ce->name)); } + + child_info->flags &= ~ZEND_ACC_OVERRIDE; } } else { zend_function **hooks = parent_info->hooks; @@ -1713,10 +1712,25 @@ void zend_build_properties_info_table(zend_class_entry *ce) } } - ZEND_HASH_MAP_FOREACH_PTR(&ce->properties_info, prop) { + ZEND_HASH_MAP_FOREACH_STR_KEY_PTR(&ce->properties_info, zend_string *key, prop) { if (prop->ce == ce && (prop->flags & ZEND_ACC_STATIC) == 0 && !(prop->flags & ZEND_ACC_VIRTUAL)) { - uint32_t prop_table_offset = OBJ_PROP_TO_NUM(!(prop->prototype->flags & ZEND_ACC_VIRTUAL) ? prop->prototype->offset : prop->offset); + const zend_property_info *root_prop = prop->prototype; + if (UNEXPECTED(root_prop->flags & ZEND_ACC_VIRTUAL)) { + /* Prototype is virtual, we need to manually hunt down the first backed property. */ + root_prop = prop; + zend_class_entry *parent_ce; + while ((parent_ce = root_prop->ce->parent)) { + zend_property_info *parent_prop = zend_hash_find_ptr(&parent_ce->properties_info, key); + if (!parent_prop + || parent_prop->prototype != prop->prototype + || (parent_prop->flags & ZEND_ACC_VIRTUAL)) { + break; + } + root_prop = parent_prop; + } + } + uint32_t prop_table_offset = OBJ_PROP_TO_NUM(root_prop->offset); table[prop_table_offset] = prop; } } ZEND_HASH_FOREACH_END(); @@ -2303,13 +2317,11 @@ static void zend_do_implement_interfaces(zend_class_entry *ce, zend_class_entry void zend_inheritance_check_override(const zend_class_entry *ce) { - zend_function *f; - if (ce->ce_flags & ZEND_ACC_TRAIT) { return; } - ZEND_HASH_MAP_FOREACH_PTR(&ce->function_table, f) { + ZEND_HASH_MAP_FOREACH_PTR(&ce->function_table, zend_function *f) { if (f->common.fn_flags & ZEND_ACC_OVERRIDE) { ZEND_ASSERT(f->type != ZEND_INTERNAL_FUNCTION); @@ -2320,14 +2332,17 @@ void zend_inheritance_check_override(const zend_class_entry *ce) } } ZEND_HASH_FOREACH_END(); - if (ce->num_hooked_props) { - zend_property_info *prop; - ZEND_HASH_MAP_FOREACH_PTR(&ce->properties_info, prop) { - if (!prop->hooks) { - continue; - } + ZEND_HASH_MAP_FOREACH_PTR(&ce->properties_info, zend_property_info *prop) { + if (prop->flags & ZEND_ACC_OVERRIDE) { + zend_error_noreturn( + E_COMPILE_ERROR, + "%s::$%s has #[\\Override] attribute, but no matching parent property exists", + ZSTR_VAL(ce->name), zend_get_unmangled_property_name(prop->name)); + } + + if (prop->hooks) { for (uint32_t i = 0; i < ZEND_PROPERTY_HOOK_COUNT; i++) { - f = prop->hooks[i]; + zend_function *f = prop->hooks[i]; if (f && f->common.fn_flags & ZEND_ACC_OVERRIDE) { ZEND_ASSERT(f->type != ZEND_INTERNAL_FUNCTION); @@ -2337,8 +2352,8 @@ void zend_inheritance_check_override(const zend_class_entry *ce) ZEND_FN_SCOPE_NAME(f), ZSTR_VAL(f->common.function_name)); } } - } ZEND_HASH_FOREACH_END(); - } + } + } ZEND_HASH_FOREACH_END(); } @@ -3546,8 +3561,6 @@ ZEND_API zend_class_entry *zend_do_link_class(zend_class_entry *ce, zend_string } #endif - bool orig_record_errors = EG(record_errors); - if (ce->ce_flags & ZEND_ACC_IMMUTABLE && is_cacheable) { if (zend_inheritance_cache_get && zend_inheritance_cache_add) { zend_class_entry *ret = zend_inheritance_cache_get(ce, parent, traits_and_interfaces); @@ -3559,16 +3572,21 @@ ZEND_API zend_class_entry *zend_do_link_class(zend_class_entry *ce, zend_string Z_CE_P(zv) = ret; return ret; } - - /* Make sure warnings (such as deprecations) thrown during inheritance - * will be recorded in the inheritance cache. */ - zend_begin_record_errors(); } else { is_cacheable = 0; } proto = ce; } + /* Delay and record warnings (such as deprecations) thrown during + * inheritance, so they will be recorded in the inheritance cache. + * Warnings must be delayed in all cases so that we get a consistent + * behavior regardless of cacheability. */ + bool orig_record_errors = EG(record_errors); + if (!orig_record_errors) { + zend_begin_record_errors(); + } + zend_try { if (ce->ce_flags & ZEND_ACC_IMMUTABLE) { /* Lazy class loading */ @@ -3759,6 +3777,7 @@ ZEND_API zend_class_entry *zend_do_link_class(zend_class_entry *ce, zend_string } if (!orig_record_errors) { + zend_emit_recorded_errors(); zend_free_recorded_errors(); } if (traits_and_interfaces) { @@ -3919,10 +3938,12 @@ ZEND_API zend_class_entry *zend_try_early_bind(zend_class_entry *ce, zend_class_ orig_linking_class = CG(current_linking_class); CG(current_linking_class) = is_cacheable ? ce : NULL; + bool orig_record_errors = EG(record_errors); + zend_try{ CG(zend_lineno) = ce->info.user.line_start; - if (is_cacheable) { + if (!orig_record_errors) { zend_begin_record_errors(); } @@ -3944,13 +3965,13 @@ ZEND_API zend_class_entry *zend_try_early_bind(zend_class_entry *ce, zend_class_ CG(current_linking_class) = orig_linking_class; } zend_catch { - EG(record_errors) = false; - zend_free_recorded_errors(); + if (!orig_record_errors) { + EG(record_errors) = false; + zend_free_recorded_errors(); + } zend_bailout(); } zend_end_try(); - EG(record_errors) = false; - if (is_cacheable) { HashTable *ht = (HashTable*)ce->inheritance_cache; zend_class_entry *new_ce; @@ -3968,6 +3989,11 @@ ZEND_API zend_class_entry *zend_try_early_bind(zend_class_entry *ce, zend_class_ } } + if (!orig_record_errors) { + zend_emit_recorded_errors(); + zend_free_recorded_errors(); + } + if (ZSTR_HAS_CE_CACHE(ce->name)) { ZSTR_SET_CE_CACHE(ce->name, ce); } diff --git a/Zend/zend_ini.c b/Zend/zend_ini.c index 199ebfb2e9b..689e76794df 100644 --- a/Zend/zend_ini.c +++ b/Zend/zend_ini.c @@ -248,10 +248,16 @@ ZEND_API zend_result zend_register_ini_entries_ex(const zend_ini_entry_def *ini_ zend_unregister_ini_entries_ex(module_number, module_type); return FAILURE; } + + zend_string *prev_value = p->value; + if (((default_value = zend_get_configuration_directive(p->name)) != NULL) && (!p->on_modify || p->on_modify(p, Z_STR_P(default_value), p->mh_arg1, p->mh_arg2, p->mh_arg3, ZEND_INI_STAGE_STARTUP) == SUCCESS)) { - p->value = zend_new_interned_string(zend_string_copy(Z_STR_P(default_value))); + /* Skip assigning the value if the handler has already done so. */ + if (p->value == prev_value) { + p->value = zend_new_interned_string(zend_string_copy(Z_STR_P(default_value))); + } } else { p->value = ini_entry->value ? zend_string_init_interned(ini_entry->value, ini_entry->value_length, 1) : NULL; @@ -389,14 +395,20 @@ ZEND_API zend_result zend_alter_ini_entry_ex(zend_string *name, zend_string *new zend_hash_add_ptr(EG(modified_ini_directives), ini_entry->name, ini_entry); } + zend_string *prev_value = ini_entry->value; duplicate = zend_string_copy(new_value); if (!ini_entry->on_modify || ini_entry->on_modify(ini_entry, duplicate, ini_entry->mh_arg1, ini_entry->mh_arg2, ini_entry->mh_arg3, stage) == SUCCESS) { - if (modified && ini_entry->orig_value != ini_entry->value) { /* we already changed the value, free the changed value */ - zend_string_release(ini_entry->value); + if (modified && ini_entry->orig_value != prev_value) { /* we already changed the value, free the changed value */ + zend_string_release(prev_value); + } + /* Skip assigning the value if the handler has already done so. */ + if (ini_entry->value == prev_value) { + ini_entry->value = duplicate; + } else { + zend_string_release(duplicate); } - ini_entry->value = duplicate; } else { zend_string_release(duplicate); return FAILURE; diff --git a/Zend/zend_iterators.c b/Zend/zend_iterators.c index f67033b1116..64dbb0541a8 100644 --- a/Zend/zend_iterators.c +++ b/Zend/zend_iterators.c @@ -31,6 +31,7 @@ static const zend_object_handlers iterator_object_handlers = { iter_wrapper_free, iter_wrapper_dtor, NULL, /* clone_obj */ + NULL, /* clone_obj_with */ NULL, /* prop read */ NULL, /* prop write */ NULL, /* read dim */ diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y index 07ea669ae8e..3f2817b26ec 100644 --- a/Zend/zend_language_parser.y +++ b/Zend/zend_language_parser.y @@ -212,7 +212,7 @@ static YYSIZE_T zend_yytnamerr(char*, const char*); %token T_INC "'++'" %token T_DEC "'--'" %token T_INT_CAST "'(int)'" -%token T_DOUBLE_CAST "'(double)'" +%token T_DOUBLE_CAST "'(float)'" %token T_STRING_CAST "'(string)'" %token T_ARRAY_CAST "'(array)'" %token T_OBJECT_CAST "'(object)'" @@ -713,15 +713,14 @@ switch_case_list: case_list: %empty { $$ = zend_ast_create_list(0, ZEND_AST_SWITCH_LIST); } - | case_list T_CASE expr case_separator inner_statement_list + | case_list T_CASE expr ':' inner_statement_list { $$ = zend_ast_list_add($1, zend_ast_create(ZEND_AST_SWITCH_CASE, $3, $5)); } - | case_list T_DEFAULT case_separator inner_statement_list + | case_list T_CASE expr ';' inner_statement_list + { $$ = zend_ast_list_add($1, zend_ast_create_ex(ZEND_AST_SWITCH_CASE, ZEND_ALT_CASE_SYNTAX, $3, $5)); } + | case_list T_DEFAULT ':' inner_statement_list { $$ = zend_ast_list_add($1, zend_ast_create(ZEND_AST_SWITCH_CASE, NULL, $4)); } -; - -case_separator: - ':' - | ';' + | case_list T_DEFAULT ';' inner_statement_list + { $$ = zend_ast_list_add($1, zend_ast_create_ex(ZEND_AST_SWITCH_CASE, ZEND_ALT_CASE_SYNTAX, NULL, $4)); } ; diff --git a/Zend/zend_language_scanner.l b/Zend/zend_language_scanner.l index 2bd21f7b4c2..d298ae8b9ea 100644 --- a/Zend/zend_language_scanner.l +++ b/Zend/zend_language_scanner.l @@ -650,7 +650,17 @@ ZEND_API zend_op_array *compile_file(zend_file_handle *file_handle, int type) } } } else { + bool orig_record_errors = EG(record_errors); + if (!orig_record_errors) { + zend_begin_record_errors(); + } + op_array = zend_compile(ZEND_USER_FUNCTION); + + if (!orig_record_errors) { + zend_emit_recorded_errors(); + zend_free_recorded_errors(); + } } zend_restore_lexical_state(&original_lex_state); @@ -1619,11 +1629,25 @@ OPTIONAL_WHITESPACE_OR_COMMENTS ({WHITESPACE}|{MULTI_LINE_COMMENT}|{SINGLE_LINE_ RETURN_TOKEN_WITH_IDENT(T_VAR); } -"("{TABS_AND_SPACES}("int"|"integer"){TABS_AND_SPACES}")" { +"("{TABS_AND_SPACES}("int"){TABS_AND_SPACES}")" { RETURN_TOKEN(T_INT_CAST); } -"("{TABS_AND_SPACES}("double"|"float"){TABS_AND_SPACES}")" { +"("{TABS_AND_SPACES}("integer"){TABS_AND_SPACES}")" { + if (PARSER_MODE()) { + zend_error(E_DEPRECATED, "Non-canonical cast (integer) is deprecated, use the (int) cast instead"); + } + RETURN_TOKEN(T_INT_CAST); +} + +"("{TABS_AND_SPACES}("float"){TABS_AND_SPACES}")" { + RETURN_TOKEN(T_DOUBLE_CAST); +} + +"("{TABS_AND_SPACES}("double"){TABS_AND_SPACES}")" { + if (PARSER_MODE()) { + zend_error(E_DEPRECATED, "Non-canonical cast (double) is deprecated, use the (float) cast instead"); + } RETURN_TOKEN(T_DOUBLE_CAST); } @@ -1635,7 +1659,14 @@ OPTIONAL_WHITESPACE_OR_COMMENTS ({WHITESPACE}|{MULTI_LINE_COMMENT}|{SINGLE_LINE_ RETURN_TOKEN(T_DOUBLE_CAST); } -"("{TABS_AND_SPACES}("string"|"binary"){TABS_AND_SPACES}")" { +"("{TABS_AND_SPACES}("string"){TABS_AND_SPACES}")" { + RETURN_TOKEN(T_STRING_CAST); +} + +"("{TABS_AND_SPACES}("binary"){TABS_AND_SPACES}")" { + if (PARSER_MODE()) { + zend_error(E_DEPRECATED, "Non-canonical cast (binary) is deprecated, use the (string) cast instead"); + } RETURN_TOKEN(T_STRING_CAST); } @@ -1647,7 +1678,14 @@ OPTIONAL_WHITESPACE_OR_COMMENTS ({WHITESPACE}|{MULTI_LINE_COMMENT}|{SINGLE_LINE_ RETURN_TOKEN(T_OBJECT_CAST); } -"("{TABS_AND_SPACES}("bool"|"boolean"){TABS_AND_SPACES}")" { +"("{TABS_AND_SPACES}("bool"){TABS_AND_SPACES}")" { + RETURN_TOKEN(T_BOOL_CAST); +} + +"("{TABS_AND_SPACES}("boolean"){TABS_AND_SPACES}")" { + if (PARSER_MODE()) { + zend_error(E_DEPRECATED, "Non-canonical cast (boolean) is deprecated, use the (bool) cast instead"); + } RETURN_TOKEN(T_BOOL_CAST); } diff --git a/Zend/zend_llist.c b/Zend/zend_llist.c index 8c42b2494ea..28a275e6fce 100644 --- a/Zend/zend_llist.c +++ b/Zend/zend_llist.c @@ -121,7 +121,6 @@ ZEND_API void zend_llist_destroy(zend_llist *l) ZEND_API void zend_llist_clean(zend_llist *l) { zend_llist_destroy(l); - l->head = l->tail = NULL; } diff --git a/Zend/zend_multiply.h b/Zend/zend_multiply.h index bdeb435d443..d3b03ac79a2 100644 --- a/Zend/zend_multiply.h +++ b/Zend/zend_multiply.h @@ -155,13 +155,15 @@ static zend_always_inline size_t zend_safe_address(size_t nmemb, size_t size, si __asm__ ("mull %3\n\tadcl $0,%1" : "=&a"(res), "=&d" (m_overflow) : "%0"(res), - "rm"(size)); + "rm"(size) + : "cc"); } else { __asm__ ("mull %3\n\taddl %4,%0\n\tadcl $0,%1" : "=&a"(res), "=&d" (m_overflow) : "%0"(res), "rm"(size), - "rm"(offset)); + "rm"(offset) + : "cc"); } if (UNEXPECTED(m_overflow)) { @@ -176,7 +178,7 @@ static zend_always_inline size_t zend_safe_address(size_t nmemb, size_t size, si static zend_always_inline size_t zend_safe_address(size_t nmemb, size_t size, size_t offset, bool *overflow) { - size_t res = nmemb; + size_t res; zend_ulong m_overflow = 0; #ifdef __ILP32__ /* x32 */ @@ -186,19 +188,30 @@ static zend_always_inline size_t zend_safe_address(size_t nmemb, size_t size, si #endif if (ZEND_CONST_COND(offset == 0, 0)) { + res = nmemb; __asm__ ("mul" LP_SUFF " %3\n\t" "adc $0,%1" : "=&a"(res), "=&d" (m_overflow) : "%0"(res), - "rm"(size)); + "rm"(size) + : "cc"); + } else if (ZEND_CONST_COND(nmemb == 1, 0)) { + res = size; + __asm__ ("add %2, %0\n\t" + "adc $0,%1" + : "+r"(res), "+r" (m_overflow) + : "rm"(offset) + : "cc"); } else { + res = nmemb; __asm__ ("mul" LP_SUFF " %3\n\t" "add %4,%0\n\t" "adc $0,%1" : "=&a"(res), "=&d" (m_overflow) : "%0"(res), "rm"(size), - "rm"(offset)); + "rm"(offset) + : "cc"); } #undef LP_SUFF if (UNEXPECTED(m_overflow)) { diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index 732b7e8f2bd..cca69e5d792 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -223,6 +223,8 @@ ZEND_API HashTable *zend_std_get_debug_info(zend_object *object, int *is_temp) / return Z_ARRVAL(retval); } } else if (Z_TYPE(retval) == IS_NULL) { + zend_error(E_DEPRECATED, "Returning null from %s::__debugInfo() is deprecated, return an empty array instead", + ZSTR_VAL(ce->name)); *is_temp = 1; ht = zend_new_array(0); return ht; @@ -285,7 +287,7 @@ static zend_always_inline bool is_derived_class(const zend_class_entry *child_cl static zend_never_inline int is_protected_compatible_scope(const zend_class_entry *ce, const zend_class_entry *scope) /* {{{ */ { return scope && - (is_derived_class(ce, scope) || is_derived_class(scope, ce)); + (ce == scope || is_derived_class(ce, scope) || is_derived_class(scope, ce)); } /* }}} */ @@ -422,7 +424,7 @@ wrong: } } else { ZEND_ASSERT(flags & ZEND_ACC_PROTECTED); - if (UNEXPECTED(!is_protected_compatible_scope(property_info->ce, scope))) { + if (UNEXPECTED(!is_protected_compatible_scope(property_info->prototype->ce, scope))) { goto wrong; } } @@ -517,7 +519,7 @@ wrong: } } else { ZEND_ASSERT(flags & ZEND_ACC_PROTECTED); - if (UNEXPECTED(!is_protected_compatible_scope(property_info->ce, scope))) { + if (UNEXPECTED(!is_protected_compatible_scope(property_info->prototype->ce, scope))) { goto wrong; } } @@ -588,7 +590,7 @@ ZEND_API bool ZEND_FASTCALL zend_asymmetric_property_has_set_access(const zend_p return true; } return EXPECTED((prop_info->flags & ZEND_ACC_PROTECTED_SET) - && is_protected_compatible_scope(prop_info->ce, scope)); + && is_protected_compatible_scope(prop_info->prototype->ce, scope)); } static void zend_property_guard_dtor(zval *el) /* {{{ */ { @@ -2033,7 +2035,7 @@ ZEND_API zval *zend_std_get_static_property_with_info(zend_class_entry *ce, zend const zend_class_entry *scope = get_fake_or_executed_scope(); if (property_info->ce != scope) { if (UNEXPECTED(property_info->flags & ZEND_ACC_PRIVATE) - || UNEXPECTED(!is_protected_compatible_scope(property_info->ce, scope))) { + || UNEXPECTED(!is_protected_compatible_scope(property_info->prototype->ce, scope))) { if (type != BP_VAR_IS) { zend_bad_property_access(property_info, ce, property_name); } @@ -2204,6 +2206,10 @@ ZEND_API int zend_std_compare_objects(zval *o1, zval *o2) /* {{{ */ } Z_PROTECT_RECURSION_P(o1); + GC_ADDREF(zobj1); + GC_ADDREF(zobj2); + int ret; + for (i = 0; i < zobj1->ce->default_properties_count; i++) { zval *p1, *p2; @@ -2218,31 +2224,45 @@ ZEND_API int zend_std_compare_objects(zval *o1, zval *o2) /* {{{ */ if (Z_TYPE_P(p1) != IS_UNDEF) { if (Z_TYPE_P(p2) != IS_UNDEF) { - int ret; - ret = zend_compare(p1, p2); if (ret != 0) { Z_UNPROTECT_RECURSION_P(o1); - return ret; + goto done; } } else { Z_UNPROTECT_RECURSION_P(o1); - return 1; + ret = 1; + goto done; } } else { if (Z_TYPE_P(p2) != IS_UNDEF) { Z_UNPROTECT_RECURSION_P(o1); - return 1; + ret = 1; + goto done; } } } Z_UNPROTECT_RECURSION_P(o1); - return 0; + ret = 0; + +done: + OBJ_RELEASE(zobj1); + OBJ_RELEASE(zobj2); + + return ret; } else { - return zend_compare_symbol_tables( + GC_ADDREF(zobj1); + GC_ADDREF(zobj2); + + int ret = zend_compare_symbol_tables( zend_std_get_properties_ex(zobj1), zend_std_get_properties_ex(zobj2)); + + OBJ_RELEASE(zobj1); + OBJ_RELEASE(zobj2); + + return ret; } } /* }}} */ @@ -2541,6 +2561,7 @@ ZEND_API const zend_object_handlers std_object_handlers = { zend_object_std_dtor, /* free_obj */ zend_objects_destroy_object, /* dtor_obj */ zend_objects_clone_obj, /* clone_obj */ + zend_objects_clone_obj_with, /* clone_obj_with */ zend_std_read_property, /* read_property */ zend_std_write_property, /* write_property */ diff --git a/Zend/zend_object_handlers.h b/Zend/zend_object_handlers.h index fb87695a2ed..84d0b57d7aa 100644 --- a/Zend/zend_object_handlers.h +++ b/Zend/zend_object_handlers.h @@ -180,6 +180,7 @@ typedef void (*zend_object_free_obj_t)(zend_object *object); typedef void (*zend_object_dtor_obj_t)(zend_object *object); typedef zend_object* (*zend_object_clone_obj_t)(zend_object *object); +typedef zend_object* (*zend_object_clone_obj_with_t)(zend_object *object, const zend_class_entry *scope, const HashTable *properties); /* Get class name for display in var_dump and other debugging functions. * Must be defined and must return a non-NULL value. */ @@ -209,6 +210,7 @@ struct _zend_object_handlers { zend_object_free_obj_t free_obj; /* required */ zend_object_dtor_obj_t dtor_obj; /* required */ zend_object_clone_obj_t clone_obj; /* optional */ + zend_object_clone_obj_with_t clone_obj_with; /* optional */ zend_object_read_property_t read_property; /* required */ zend_object_write_property_t write_property; /* required */ zend_object_read_dimension_t read_dimension; /* required */ diff --git a/Zend/zend_objects.c b/Zend/zend_objects.c index 45bbc60cdb3..4b4187f4238 100644 --- a/Zend/zend_objects.c +++ b/Zend/zend_objects.c @@ -264,7 +264,6 @@ ZEND_API void ZEND_FASTCALL zend_objects_clone_members(zend_object *new_object, } if (has_clone_method) { - GC_ADDREF(new_object); zend_call_known_instance_method_with_0_params(new_object->ce->clone, new_object, NULL); if (ZEND_CLASS_HAS_READONLY_PROPS(new_object->ce)) { @@ -274,11 +273,55 @@ ZEND_API void ZEND_FASTCALL zend_objects_clone_members(zend_object *new_object, Z_PROP_FLAG_P(prop) &= ~IS_PROP_REINITABLE; } } - - OBJ_RELEASE(new_object); } } +ZEND_API zend_object *zend_objects_clone_obj_with(zend_object *old_object, const zend_class_entry *scope, const HashTable *properties) +{ + zend_object *new_object = old_object->handlers->clone_obj(old_object); + + if (EXPECTED(!EG(exception))) { + /* Unlock readonly properties once more. */ + if (ZEND_CLASS_HAS_READONLY_PROPS(new_object->ce)) { + for (uint32_t i = 0; i < new_object->ce->default_properties_count; i++) { + zval* prop = OBJ_PROP_NUM(new_object, i); + Z_PROP_FLAG_P(prop) |= IS_PROP_REINITABLE; + } + } + + const zend_class_entry *old_scope = EG(fake_scope); + + EG(fake_scope) = scope; + + ZEND_HASH_FOREACH_KEY_VAL(properties, zend_ulong num_key, zend_string *key, zval *val) { + if (UNEXPECTED(Z_ISREF_P(val))) { + if (Z_REFCOUNT_P(val) == 1) { + val = Z_REFVAL_P(val); + } else { + zend_throw_error(NULL, "Cannot assign by reference when cloning with updated properties"); + break; + } + } + + if (UNEXPECTED(key == NULL)) { + key = zend_long_to_str(num_key); + new_object->handlers->write_property(new_object, key, val, NULL); + zend_string_release_ex(key, false); + } else { + new_object->handlers->write_property(new_object, key, val, NULL); + } + + if (UNEXPECTED(EG(exception))) { + break; + } + } ZEND_HASH_FOREACH_END(); + + EG(fake_scope) = old_scope; + } + + return new_object; +} + ZEND_API zend_object *zend_objects_clone_obj(zend_object *old_object) { zend_object *new_object; diff --git a/Zend/zend_objects.h b/Zend/zend_objects.h index 41e3bcd9594..712fd442da5 100644 --- a/Zend/zend_objects.h +++ b/Zend/zend_objects.h @@ -30,6 +30,7 @@ ZEND_API void ZEND_FASTCALL zend_objects_clone_members(zend_object *new_object, ZEND_API void zend_object_std_dtor(zend_object *object); ZEND_API void zend_objects_destroy_object(zend_object *object); ZEND_API zend_object *zend_objects_clone_obj(zend_object *object); +ZEND_API zend_object *zend_objects_clone_obj_with(zend_object *object, const zend_class_entry *scope, const HashTable *properties); void zend_object_dtor_dynamic_properties(zend_object *object); void zend_object_dtor_property(zend_object *object, zval *p); diff --git a/Zend/zend_opcode.c b/Zend/zend_opcode.c index 6e7d31e15a4..f3631104c62 100644 --- a/Zend/zend_opcode.c +++ b/Zend/zend_opcode.c @@ -709,7 +709,7 @@ static void zend_check_finally_breakout(zend_op_array *op_array, uint32_t op_num } } -static uint32_t zend_get_brk_cont_target(const zend_op_array *op_array, const zend_op *opline) { +static uint32_t zend_get_brk_cont_target(const zend_op *opline) { int nest_levels = opline->op2.num; int array_offset = opline->op1.num; zend_brk_cont_element *jmp_to; @@ -903,7 +903,8 @@ static bool keeps_op1_alive(zend_op *opline) { || opline->opcode == ZEND_MATCH_ERROR || opline->opcode == ZEND_FETCH_LIST_R || opline->opcode == ZEND_FETCH_LIST_W - || opline->opcode == ZEND_COPY_TMP) { + || opline->opcode == ZEND_COPY_TMP + || opline->opcode == ZEND_EXT_STMT) { return 1; } ZEND_ASSERT(opline->opcode != ZEND_FE_FETCH_R @@ -1120,7 +1121,7 @@ ZEND_API void pass_two(zend_op_array *op_array) case ZEND_BRK: case ZEND_CONT: { - uint32_t jmp_target = zend_get_brk_cont_target(op_array, opline); + uint32_t jmp_target = zend_get_brk_cont_target(opline); if (op_array->fn_flags & ZEND_ACC_HAS_FINALLY_BLOCK) { zend_check_finally_breakout(op_array, opline - op_array->opcodes, jmp_target); diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c index bc115e1aa78..957d93f9849 100644 --- a/Zend/zend_operators.c +++ b/Zend/zend_operators.c @@ -3422,7 +3422,19 @@ static int hash_zval_compare_function(zval *z1, zval *z2) /* {{{ */ ZEND_API int ZEND_FASTCALL zend_compare_symbol_tables(HashTable *ht1, HashTable *ht2) /* {{{ */ { - return ht1 == ht2 ? 0 : zend_hash_compare(ht1, ht2, (compare_func_t) hash_zval_compare_function, 0); + if (ht1 == ht2) { + return 0; + } + + GC_TRY_ADDREF(ht1); + GC_TRY_ADDREF(ht2); + + int ret = zend_hash_compare(ht1, ht2, (compare_func_t) hash_zval_compare_function, 0); + + GC_TRY_DTOR_NO_REF(ht1); + GC_TRY_DTOR_NO_REF(ht2); + + return ret; } /* }}} */ diff --git a/Zend/zend_portability.h b/Zend/zend_portability.h index 1b28f21c39a..0fa4e91c6c2 100644 --- a/Zend/zend_portability.h +++ b/Zend/zend_portability.h @@ -769,7 +769,7 @@ extern "C++" { # define ZEND_INDIRECT_RETURN #endif -#if __has_attribute(nonstring) && defined(__GNUC__) && !defined(__clang__) && __GNUC__ >= 15 +#if __has_attribute(nonstring) && defined(__GNUC__) && ((!defined(__clang__) && __GNUC__ >= 15) || (defined(__clang_major__) && __clang_major__ >= 20)) # define ZEND_NONSTRING __attribute__((nonstring)) #else # define ZEND_NONSTRING @@ -799,7 +799,9 @@ extern "C++" { /** @deprecated */ #define ZEND_CGG_DIAGNOSTIC_IGNORED_END ZEND_DIAGNOSTIC_IGNORED_END -#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) /* C11 */ +#if defined(__cplusplus) +# define ZEND_STATIC_ASSERT(c, m) static_assert((c), m) +#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) /* C11 */ # define ZEND_STATIC_ASSERT(c, m) _Static_assert((c), m) #else # define ZEND_STATIC_ASSERT(c, m) diff --git a/Zend/zend_types.h b/Zend/zend_types.h index 4a6d00b9d73..a3d3e4da636 100644 --- a/Zend/zend_types.h +++ b/Zend/zend_types.h @@ -753,6 +753,18 @@ static zend_always_inline uint8_t zval_get_type(const zval* pz) { } \ } while (0) +#define GC_TRY_DTOR_NO_REF(p) \ + do { \ + zend_refcounted_h *_p = &(p)->gc; \ + if (!(_p->u.type_info & GC_IMMUTABLE)) { \ + if (zend_gc_delref(_p) == 0) { \ + rc_dtor_func((zend_refcounted *)_p); \ + } else { \ + gc_check_possible_root_no_ref((zend_refcounted *)_p); \ + } \ + } \ + } while (0) + #define GC_TYPE_MASK 0x0000000f #define GC_FLAGS_MASK 0x000003f0 #define GC_INFO_MASK 0xfffffc00 diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index c0e05aef470..d305b0a9516 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -5392,6 +5392,11 @@ ZEND_VM_C_LABEL(send_again): } name = Z_STR_P(&key); + + zend_ulong tmp; + if (ZEND_HANDLE_NUMERIC(name, tmp)) { + name = NULL; + } } } @@ -6006,7 +6011,8 @@ ZEND_VM_COLD_CONST_HANDLER(110, ZEND_CLONE, CONST|TMPVAR|UNUSED|THIS|CV, ANY) SAVE_OPLINE(); obj = GET_OP1_OBJ_ZVAL_PTR_UNDEF(BP_VAR_R); - /* ZEND_CLONE also exists as the clone() function and both implementations must be kept in sync. */ + /* ZEND_CLONE also exists as the clone() function and both implementations must be kept in sync. + * The OPcode intentionally does not support a clone-with property list to keep it simple. */ do { if (OP1_TYPE == IS_CONST || @@ -6319,17 +6325,22 @@ ZEND_VM_C_LABEL(add_unpack_again): zval *val; if (HT_IS_PACKED(ht) && (zend_hash_num_elements(result_ht) == 0 || HT_IS_PACKED(result_ht))) { - zend_hash_extend(result_ht, result_ht->nNumUsed + zend_hash_num_elements(ht), 1); - ZEND_HASH_FILL_PACKED(result_ht) { - ZEND_HASH_PACKED_FOREACH_VAL(ht, val) { - if (UNEXPECTED(Z_ISREF_P(val)) && - UNEXPECTED(Z_REFCOUNT_P(val) == 1)) { - val = Z_REFVAL_P(val); - } - Z_TRY_ADDREF_P(val); - ZEND_HASH_FILL_ADD(val); - } ZEND_HASH_FOREACH_END(); - } ZEND_HASH_FILL_END(); + /* zend_hash_extend() skips initialization when the number of elements is 0, + * but the code below expects that result_ht is initialized as packed. + * We can just skip the work in that case. */ + if (result_ht->nNumUsed + zend_hash_num_elements(ht) > 0) { + zend_hash_extend(result_ht, result_ht->nNumUsed + zend_hash_num_elements(ht), 1); + ZEND_HASH_FILL_PACKED(result_ht) { + ZEND_HASH_PACKED_FOREACH_VAL(ht, val) { + if (UNEXPECTED(Z_ISREF_P(val)) && + UNEXPECTED(Z_REFCOUNT_P(val) == 1)) { + val = Z_REFVAL_P(val); + } + Z_TRY_ADDREF_P(val); + ZEND_HASH_FILL_ADD(val); + } ZEND_HASH_FOREACH_END(); + } ZEND_HASH_FILL_END(); + } } else { zend_string *key; @@ -7932,7 +7943,7 @@ ZEND_VM_HANDLER(145, ZEND_DECLARE_CLASS_DELAYED, CONST, CONST) if (zv) { SAVE_OPLINE(); ce = zend_bind_class_in_slot(zv, lcname, Z_STR_P(RT_CONSTANT(opline, opline->op2))); - if (!ce) { + if (EG(exception)) { HANDLE_EXCEPTION(); } } @@ -7956,7 +7967,7 @@ ZEND_VM_HANDLER(146, ZEND_DECLARE_ANON_CLASS, ANY, ANY, CACHE_SLOT) if (!(ce->ce_flags & ZEND_ACC_LINKED)) { SAVE_OPLINE(); ce = zend_do_link_class(ce, (OP2_TYPE == IS_CONST) ? Z_STR_P(RT_CONSTANT(opline, opline->op2)) : NULL, rtd_key); - if (!ce) { + if (EG(exception)) { HANDLE_EXCEPTION(); } } diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 387a05943dd..677166304f5 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -321,14 +321,14 @@ static uint8_t zend_user_opcodes[256] = {0, #define SPEC_RULE_OBSERVER 0x02000000 static const uint32_t *zend_spec_handlers; -static const void * const *zend_opcode_handlers; +static zend_vm_opcode_handler_t const *zend_opcode_handlers; static int zend_handlers_count; #if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID) -static const void * const * zend_opcode_handler_funcs; +static zend_vm_opcode_handler_func_t const * zend_opcode_handler_funcs; static zend_op hybrid_halt_op; #endif #if (ZEND_VM_KIND != ZEND_VM_KIND_HYBRID) || !ZEND_VM_SPEC -static const void *zend_vm_get_opcode_handler(uint8_t opcode, const zend_op* op); +static zend_vm_opcode_handler_t zend_vm_get_opcode_handler(uint8_t opcode, const zend_op* op); #endif #if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID) @@ -2518,6 +2518,11 @@ send_again: } name = Z_STR_P(&key); + + zend_ulong tmp; + if (ZEND_HANDLE_NUMERIC(name, tmp)) { + name = NULL; + } } } @@ -2814,17 +2819,22 @@ add_unpack_again: zval *val; if (HT_IS_PACKED(ht) && (zend_hash_num_elements(result_ht) == 0 || HT_IS_PACKED(result_ht))) { - zend_hash_extend(result_ht, result_ht->nNumUsed + zend_hash_num_elements(ht), 1); - ZEND_HASH_FILL_PACKED(result_ht) { - ZEND_HASH_PACKED_FOREACH_VAL(ht, val) { - if (UNEXPECTED(Z_ISREF_P(val)) && - UNEXPECTED(Z_REFCOUNT_P(val) == 1)) { - val = Z_REFVAL_P(val); - } - Z_TRY_ADDREF_P(val); - ZEND_HASH_FILL_ADD(val); - } ZEND_HASH_FOREACH_END(); - } ZEND_HASH_FILL_END(); + /* zend_hash_extend() skips initialization when the number of elements is 0, + * but the code below expects that result_ht is initialized as packed. + * We can just skip the work in that case. */ + if (result_ht->nNumUsed + zend_hash_num_elements(ht) > 0) { + zend_hash_extend(result_ht, result_ht->nNumUsed + zend_hash_num_elements(ht), 1); + ZEND_HASH_FILL_PACKED(result_ht) { + ZEND_HASH_PACKED_FOREACH_VAL(ht, val) { + if (UNEXPECTED(Z_ISREF_P(val)) && + UNEXPECTED(Z_REFCOUNT_P(val) == 1)) { + val = Z_REFVAL_P(val); + } + Z_TRY_ADDREF_P(val); + ZEND_HASH_FILL_ADD(val); + } ZEND_HASH_FOREACH_END(); + } ZEND_HASH_FILL_END(); + } } else { zend_string *key; @@ -3207,7 +3217,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_ANON_CLASS_SPEC_HANDLE if (!(ce->ce_flags & ZEND_ACC_LINKED)) { SAVE_OPLINE(); ce = zend_do_link_class(ce, (opline->op2_type == IS_CONST) ? Z_STR_P(RT_CONSTANT(opline, opline->op2)) : NULL, rtd_key); - if (!ce) { + if (EG(exception)) { HANDLE_EXCEPTION(); } } @@ -5180,7 +5190,8 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CLONE_SPEC_CONST_ SAVE_OPLINE(); obj = RT_CONSTANT(opline, opline->op1); - /* ZEND_CLONE also exists as the clone() function and both implementations must be kept in sync. */ + /* ZEND_CLONE also exists as the clone() function and both implementations must be kept in sync. + * The OPcode intentionally does not support a clone-with property list to keep it simple. */ do { if (IS_CONST == IS_CONST || @@ -8008,7 +8019,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_CLASS_DELAYED_SPEC_CON if (zv) { SAVE_OPLINE(); ce = zend_bind_class_in_slot(zv, lcname, Z_STR_P(RT_CONSTANT(opline, opline->op2))); - if (!ce) { + if (EG(exception)) { HANDLE_EXCEPTION(); } } @@ -15427,7 +15438,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CLONE_SPEC_TMPVAR_HANDLER(ZEND SAVE_OPLINE(); obj = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - /* ZEND_CLONE also exists as the clone() function and both implementations must be kept in sync. */ + /* ZEND_CLONE also exists as the clone() function and both implementations must be kept in sync. + * The OPcode intentionally does not support a clone-with property list to keep it simple. */ do { if ((IS_TMP_VAR|IS_VAR) == IS_CONST || @@ -33522,7 +33534,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CLONE_SPEC_UNUSED_HANDLER(ZEND SAVE_OPLINE(); obj = &EX(This); - /* ZEND_CLONE also exists as the clone() function and both implementations must be kept in sync. */ + /* ZEND_CLONE also exists as the clone() function and both implementations must be kept in sync. + * The OPcode intentionally does not support a clone-with property list to keep it simple. */ do { if (IS_UNUSED == IS_CONST || @@ -41041,7 +41054,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CLONE_SPEC_CV_HANDLER(ZEND_OPC SAVE_OPLINE(); obj = EX_VAR(opline->op1.var); - /* ZEND_CLONE also exists as the clone() function and both implementations must be kept in sync. */ + /* ZEND_CLONE also exists as the clone() function and both implementations must be kept in sync. + * The OPcode intentionally does not support a clone-with property list to keep it simple. */ do { if (IS_CV == IS_CONST || @@ -58657,8 +58671,8 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_USED_LABEL, (void*)&&ZEND_NULL_LABEL }; - zend_opcode_handlers = (const void **) labels; - zend_handlers_count = sizeof(labels) / sizeof(void*); + zend_opcode_handlers = (zend_vm_opcode_handler_t*) labels; + zend_handlers_count = sizeof(labels) / sizeof(labels[0]); memset(&hybrid_halt_op, 0, sizeof(hybrid_halt_op)); hybrid_halt_op.handler = (void*)&&HYBRID_HALT_LABEL; #ifdef ZEND_VM_HYBRID_JIT_RED_ZONE_SIZE @@ -64389,7 +64403,11 @@ ZEND_API void zend_execute(zend_op_array *op_array, zval *return_value) void zend_vm_init(void) { - static const void * const labels[] = { +#if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID) + static zend_vm_opcode_handler_func_t const labels[] = { +#else + static zend_vm_opcode_handler_t const labels[] = { +#endif ZEND_NOP_SPEC_HANDLER, ZEND_ADD_SPEC_CONST_CONST_HANDLER, ZEND_ADD_SPEC_CONST_TMPVARCV_HANDLER, @@ -68149,7 +68167,7 @@ void zend_vm_init(void) execute_ex(NULL); #else zend_opcode_handlers = labels; - zend_handlers_count = sizeof(labels) / sizeof(void*); + zend_handlers_count = sizeof(labels) / sizeof(labels[0]); zend_spec_handlers = specs; #endif VM_TRACE_START(); @@ -68191,7 +68209,7 @@ ZEND_API void ZEND_FASTCALL zend_serialize_opcode_handler(zend_op *op) } zv = zend_hash_index_find(zend_handlers_table, (zend_long)(uintptr_t)op->handler); ZEND_ASSERT(zv != NULL); - op->handler = (const void *)(uintptr_t)Z_LVAL_P(zv); + op->handler = (zend_vm_opcode_handler_t)(uintptr_t)Z_LVAL_P(zv); } ZEND_API void ZEND_FASTCALL zend_deserialize_opcode_handler(zend_op *op) @@ -68277,7 +68295,7 @@ static uint32_t ZEND_FASTCALL zend_vm_get_opcode_handler_idx(uint32_t spec, cons } #if (ZEND_VM_KIND != ZEND_VM_KIND_HYBRID) || !ZEND_VM_SPEC -static const void *zend_vm_get_opcode_handler(uint8_t opcode, const zend_op* op) +static zend_vm_opcode_handler_t zend_vm_get_opcode_handler(uint8_t opcode, const zend_op* op) { return zend_opcode_handlers[zend_vm_get_opcode_handler_idx(zend_spec_handlers[opcode], op)]; } diff --git a/Zend/zend_vm_execute.skl b/Zend/zend_vm_execute.skl index 2417b858b5b..3eabb4c46be 100644 --- a/Zend/zend_vm_execute.skl +++ b/Zend/zend_vm_execute.skl @@ -126,7 +126,7 @@ ZEND_API void ZEND_FASTCALL zend_serialize_opcode_handler(zend_op *op) } zv = zend_hash_index_find(zend_handlers_table, (zend_long)(uintptr_t)op->handler); ZEND_ASSERT(zv != NULL); - op->handler = (const void *)(uintptr_t)Z_LVAL_P(zv); + op->handler = (zend_vm_opcode_handler_t)(uintptr_t)Z_LVAL_P(zv); } ZEND_API void ZEND_FASTCALL zend_deserialize_opcode_handler(zend_op *op) diff --git a/Zend/zend_vm_gen.php b/Zend/zend_vm_gen.php index dbd7da0430f..813e629fea0 100755 --- a/Zend/zend_vm_gen.php +++ b/Zend/zend_vm_gen.php @@ -1186,7 +1186,7 @@ function gen_null_label($f, $kind, $prolog) { out($f,$prolog."ZEND_NULL_HANDLER,\n"); break; case ZEND_VM_KIND_SWITCH: - out($f,$prolog."(void*)(uintptr_t)-1,\n"); + out($f,$prolog."-1,\n"); break; case ZEND_VM_KIND_GOTO: out($f,$prolog."(void*)&&ZEND_NULL_LABEL,\n"); @@ -1388,7 +1388,7 @@ function gen_labels($f, $spec, $kind, $prolog, &$specs, $switch_labels = array() out($f,"$prolog{$spec_name}_HANDLER,\n"); break; case ZEND_VM_KIND_SWITCH: - out($f,$prolog."(void*)(uintptr_t)$switch_labels[$spec_name],\n"); + out($f,$prolog."$switch_labels[$spec_name],\n"); break; case ZEND_VM_KIND_GOTO: out($f,$prolog."(void*)&&{$spec_name}_LABEL,\n"); @@ -1436,7 +1436,7 @@ function gen_labels($f, $spec, $kind, $prolog, &$specs, $switch_labels = array() out($f,$prolog."ZEND_NULL_HANDLER,\n"); break; case ZEND_VM_KIND_SWITCH: - out($f,$prolog."(void*)(uintptr_t)-1,\n"); + out($f,$prolog."-1,\n"); break; case ZEND_VM_KIND_GOTO: out($f,$prolog."(void*)&&ZEND_NULL_LABEL,\n"); @@ -1467,7 +1467,7 @@ function gen_labels($f, $spec, $kind, $prolog, &$specs, $switch_labels = array() out($f,$prolog.$dsc["op"]."_HANDLER,\n"); break; case ZEND_VM_KIND_SWITCH: - out($f,$prolog."(void*)(uintptr_t)".((string)$num).",\n"); + out($f,$prolog.((string)$num).",\n"); break; case ZEND_VM_KIND_GOTO: out($f,$prolog."(void*)&&".$dsc["op"]."_LABEL,\n"); @@ -1480,7 +1480,7 @@ function gen_labels($f, $spec, $kind, $prolog, &$specs, $switch_labels = array() out($f,$prolog."ZEND_NULL_HANDLER,\n"); break; case ZEND_VM_KIND_SWITCH: - out($f,$prolog."(void*)(uintptr_t)-1,\n"); + out($f,$prolog."-1,\n"); break; case ZEND_VM_KIND_GOTO: out($f,$prolog."(void*)&&ZEND_NULL_LABEL,\n"); @@ -1497,7 +1497,7 @@ function gen_labels($f, $spec, $kind, $prolog, &$specs, $switch_labels = array() out($f,$prolog."ZEND_NULL_HANDLER\n"); break; case ZEND_VM_KIND_SWITCH: - out($f,$prolog."(void*)(uintptr_t)-1\n"); + out($f,$prolog."-1\n"); break; case ZEND_VM_KIND_GOTO: out($f,$prolog."(void*)&&ZEND_NULL_LABEL\n"); @@ -1813,16 +1813,16 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name) out($f,"#define SPEC_RULE_OBSERVER 0x02000000\n"); out($f,"\n"); out($f,"static const uint32_t *zend_spec_handlers;\n"); - out($f,"static const void * const *zend_opcode_handlers;\n"); + out($f,"static zend_vm_opcode_handler_t const *zend_opcode_handlers;\n"); out($f,"static int zend_handlers_count;\n"); if ($kind == ZEND_VM_KIND_HYBRID) { out($f,"#if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)\n"); - out($f,"static const void * const * zend_opcode_handler_funcs;\n"); + out($f,"static zend_vm_opcode_handler_func_t const * zend_opcode_handler_funcs;\n"); out($f,"static zend_op hybrid_halt_op;\n"); out($f,"#endif\n"); } out($f,"#if (ZEND_VM_KIND != ZEND_VM_KIND_HYBRID) || !ZEND_VM_SPEC\n"); - out($f,"static const void *zend_vm_get_opcode_handler(uint8_t opcode, const zend_op* op);\n"); + out($f,"static zend_vm_opcode_handler_t zend_vm_get_opcode_handler(uint8_t opcode, const zend_op* op);\n"); out($f,"#endif\n\n"); if ($kind == ZEND_VM_KIND_HYBRID) { out($f,"#if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)\n"); @@ -2040,7 +2040,7 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name) break; case "HELPER_VARS": if ($kind == ZEND_VM_KIND_SWITCH) { - out($f,$m[1]."const void *dispatch_handler;\n"); + out($f,$m[1]."zend_vm_opcode_handler_t dispatch_handler;\n"); } if ($kind != ZEND_VM_KIND_CALL && count($params)) { if ($kind == ZEND_VM_KIND_HYBRID) { @@ -2097,8 +2097,8 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name) out($f,$prolog."\tstatic const void * const labels[] = {\n"); gen_labels($f, $spec, ($kind == ZEND_VM_KIND_HYBRID) ? ZEND_VM_KIND_GOTO : $kind, $prolog."\t\t", $specs); out($f,$prolog."\t};\n"); - out($f,$prolog."\tzend_opcode_handlers = (const void **) labels;\n"); - out($f,$prolog."\tzend_handlers_count = sizeof(labels) / sizeof(void*);\n"); + out($f,$prolog."\tzend_opcode_handlers = (zend_vm_opcode_handler_t*) labels;\n"); + out($f,$prolog."\tzend_handlers_count = sizeof(labels) / sizeof(labels[0]);\n"); if ($kind == ZEND_VM_KIND_HYBRID) { out($f,$prolog."\tmemset(&hybrid_halt_op, 0, sizeof(hybrid_halt_op));\n"); out($f,$prolog."\thybrid_halt_op.handler = (void*)&&HYBRID_HALT_LABEL;\n"); @@ -2212,7 +2212,11 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name) out($f,$prolog."zend_spec_handlers = specs;\n"); out($f,$prolog.$executor_name."_ex(NULL);\n"); } else { - out($f,$prolog."static const void * const labels[] = {\n"); + out($f,"#if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)\n"); + out($f,$prolog."static zend_vm_opcode_handler_func_t const labels[] = {\n"); + out($f,"#else\n"); + out($f,$prolog."static zend_vm_opcode_handler_t const labels[] = {\n"); + out($f,"#endif\n"); gen_labels($f, $spec, ($kind == ZEND_VM_KIND_HYBRID) ? ZEND_VM_KIND_CALL : $kind, $prolog."\t", $specs, $switch_labels); out($f,$prolog."};\n"); out($f,$prolog."static const uint32_t specs[] = {\n"); @@ -2226,7 +2230,7 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name) out($f,"#else\n"); } out($f,$prolog."zend_opcode_handlers = labels;\n"); - out($f,$prolog."zend_handlers_count = sizeof(labels) / sizeof(void*);\n"); + out($f,$prolog."zend_handlers_count = sizeof(labels) / sizeof(labels[0]);\n"); out($f,$prolog."zend_spec_handlers = specs;\n"); if ($kind == ZEND_VM_KIND_HYBRID) { out($f,"#endif\n"); @@ -2359,6 +2363,20 @@ function gen_vm_opcodes_header( $str .= "# endif\n"; $str .= "#endif\n"; $str .= "\n"; + $str .= "#if ZEND_VM_KIND == ZEND_VM_KIND_HYBRID\n"; + $str .= "typedef const void* zend_vm_opcode_handler_t;\n"; + $str .= "typedef void (ZEND_FASTCALL *zend_vm_opcode_handler_func_t)(void);\n"; + $str .= "#elif ZEND_VM_KIND == ZEND_VM_KIND_CALL\n"; + $str .= "typedef const struct _zend_op *(ZEND_FASTCALL *zend_vm_opcode_handler_t)(struct _zend_execute_data *execute_data, const struct _zend_op *opline);\n"; + $str .= "typedef const struct _zend_op *(ZEND_FASTCALL *zend_vm_opcode_handler_func_t)(struct _zend_execute_data *execute_data, const struct _zend_op *opline);\n"; + $str .= "#elif ZEND_VM_KIND == ZEND_VM_KIND_SWITCH\n"; + $str .= "typedef int zend_vm_opcode_handler_t;\n"; + $str .= "#elif ZEND_VM_KIND == ZEND_VM_KIND_GOTO\n"; + $str .= "typedef const void* zend_vm_opcode_handler_t;\n"; + $str .= "#else\n"; + $str .= "# error\n"; + $str .= "#endif\n"; + $str .= "\n"; foreach ($vm_op_flags as $name => $val) { $str .= sprintf("#define %-24s 0x%08x\n", $name, $val); } @@ -2840,7 +2858,7 @@ function gen_vm($def, $skel) { } out($f, "}\n\n"); out($f, "#if (ZEND_VM_KIND != ZEND_VM_KIND_HYBRID) || !ZEND_VM_SPEC\n"); - out($f, "static const void *zend_vm_get_opcode_handler(uint8_t opcode, const zend_op* op)\n"); + out($f, "static zend_vm_opcode_handler_t zend_vm_get_opcode_handler(uint8_t opcode, const zend_op* op)\n"); out($f, "{\n"); if (!ZEND_VM_SPEC) { out($f, "\treturn zend_opcode_handlers[zend_vm_get_opcode_handler_idx(opcode, op)];\n"); diff --git a/Zend/zend_vm_opcodes.h b/Zend/zend_vm_opcodes.h index 29469bb5f7d..e8e03a534b0 100644 --- a/Zend/zend_vm_opcodes.h +++ b/Zend/zend_vm_opcodes.h @@ -42,6 +42,20 @@ # endif #endif +#if ZEND_VM_KIND == ZEND_VM_KIND_HYBRID +typedef const void* zend_vm_opcode_handler_t; +typedef void (ZEND_FASTCALL *zend_vm_opcode_handler_func_t)(void); +#elif ZEND_VM_KIND == ZEND_VM_KIND_CALL +typedef const struct _zend_op *(ZEND_FASTCALL *zend_vm_opcode_handler_t)(struct _zend_execute_data *execute_data, const struct _zend_op *opline); +typedef const struct _zend_op *(ZEND_FASTCALL *zend_vm_opcode_handler_func_t)(struct _zend_execute_data *execute_data, const struct _zend_op *opline); +#elif ZEND_VM_KIND == ZEND_VM_KIND_SWITCH +typedef int zend_vm_opcode_handler_t; +#elif ZEND_VM_KIND == ZEND_VM_KIND_GOTO +typedef const void* zend_vm_opcode_handler_t; +#else +# error +#endif + #define ZEND_VM_OP_SPEC 0x00000001 #define ZEND_VM_OP_CONST 0x00000002 #define ZEND_VM_OP_TMPVAR 0x00000004 diff --git a/Zend/zend_weakrefs.c b/Zend/zend_weakrefs.c index cf363cd1259..fb564a99e25 100644 --- a/Zend/zend_weakrefs.c +++ b/Zend/zend_weakrefs.c @@ -648,7 +648,7 @@ static void zend_weakmap_iterator_get_current_key(zend_object_iterator *obj_iter zend_string *string_key; zend_ulong num_key; - int key_type = zend_hash_get_current_key_ex(&wm->ht, &string_key, &num_key, pos); + zend_hash_key_type key_type = zend_hash_get_current_key_ex(&wm->ht, &string_key, &num_key, pos); if (key_type == HASH_KEY_NON_EXISTENT) { ZVAL_NULL(key); return; diff --git a/benchmark/generate_diff.php b/benchmark/generate_diff.php index 94c020df4b9..466a6ae0e1e 100644 --- a/benchmark/generate_diff.php +++ b/benchmark/generate_diff.php @@ -62,7 +62,7 @@ function formatDiff(?int $baseInstructions, int $headInstructions): string { } function find_benchmarked_commit_hash(string $repo, string $commitHash): ?string { - $repeat = 10; + $repeat = 100; while (true) { if ($repeat-- <= 0) { diff --git a/build/Makefile.global b/build/Makefile.global index 32605a203e1..16d57b54c83 100644 --- a/build/Makefile.global +++ b/build/Makefile.global @@ -89,7 +89,7 @@ PHP_TEST_SHARED_EXTENSIONS = ` \ . $$i; $(top_srcdir)/build/shtool echo -n -- " -d zend_extension=$(top_builddir)/modules/$$dlname"; \ done; \ fi` -PHP_DEPRECATED_DIRECTIVES_REGEX = '^(magic_quotes_(gpc|runtime|sybase)?|(zend_)?extension(_debug)?(_ts)?|session\.sid_(length|bits_per_character))[\t\ ]*=' +PHP_DEPRECATED_DIRECTIVES_REGEX = '^[\t\ ]*(magic_quotes_(gpc|runtime|sybase)?|(zend_)?extension(_debug)?(_ts)?|session\.sid_(length|bits_per_character))[\t\ ]*=' test: all @if test ! -z "$(PHP_EXECUTABLE)" && test -x "$(PHP_EXECUTABLE)"; then \ diff --git a/build/ax_check_compile_flag.m4 b/build/ax_check_compile_flag.m4 index 68fd43d5ddb..54191c55353 100644 --- a/build/ax_check_compile_flag.m4 +++ b/build/ax_check_compile_flag.m4 @@ -34,14 +34,24 @@ # and this notice are preserved. This file is offered as-is, without any # warranty. -#serial 7 +#serial 11 AC_DEFUN([AX_CHECK_COMPILE_FLAG], [AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl AC_CACHE_CHECK([whether the _AC_LANG compiler accepts $1], CACHEVAR, [ ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS - _AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1" + if test x"m4_case(_AC_LANG, + [C], [$GCC], + [C++], [$GXX], + [Fortran], [$GFC], + [Fortran 77], [$G77], + [Objective C], [$GOBJC], + [Objective C++], [$GOBJCXX], + [no])" = xyes ; then + add_gnu_werror="-Werror" + fi + _AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1 $add_gnu_werror" AC_COMPILE_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])], [AS_VAR_SET(CACHEVAR,[yes])], [AS_VAR_SET(CACHEVAR,[no])]) diff --git a/build/gen_stub.php b/build/gen_stub.php index 5f8af2a2a92..4164e2aa486 100755 --- a/build/gen_stub.php +++ b/build/gen_stub.php @@ -54,7 +54,7 @@ function processDirectory(string $dir, Context $context): array { ); foreach ($it as $file) { $pathName = $file->getPathName(); - if (preg_match('/\.stub\.php$/', $pathName)) { + if (substr($pathName, -9) === '.stub.php') { $pathNames[] = $pathName; } } @@ -84,7 +84,7 @@ function processStubFile(string $stubFile, Context $context, bool $includeOnly = $legacyFile = "{$stubFilenameWithoutExtension}_legacy_arginfo.h"; $stubCode = file_get_contents($stubFile); - $stubHash = computeStubHash($stubCode); + $stubHash = sha1(str_replace("\r\n", "\n", $stubCode)); $oldStubHash = extractStubHash($arginfoFile); if ($stubHash === $oldStubHash && !$context->forceParse) { /* Stub file did not change, do not regenerate. */ @@ -153,10 +153,6 @@ function processStubFile(string $stubFile, Context $context, bool $includeOnly = } } -function computeStubHash(string $stubCode): string { - return sha1(str_replace("\r\n", "\n", $stubCode)); -} - function extractStubHash(string $arginfoFile): ?string { if (!file_exists($arginfoFile)) { return null; @@ -361,77 +357,49 @@ class SimpleType { return $this->isBuiltin && $this->name === 'mixed'; } - public function toTypeCode(): string { + private function toTypeInfo(): array { assert($this->isBuiltin); + switch ($this->name) { - case "bool": - return "_IS_BOOL"; - case "int": - return "IS_LONG"; - case "float": - return "IS_DOUBLE"; - case "string": - return "IS_STRING"; - case "array": - return "IS_ARRAY"; - case "object": - return "IS_OBJECT"; - case "void": - return "IS_VOID"; - case "callable": - return "IS_CALLABLE"; - case "mixed": - return "IS_MIXED"; - case "static": - return "IS_STATIC"; - case "never": - return "IS_NEVER"; case "null": - return "IS_NULL"; + return ["IS_NULL", "MAY_BE_NULL"]; case "false": - return "IS_FALSE"; + return ["IS_FALSE", "MAY_BE_FALSE"]; case "true": - return "IS_TRUE"; + return ["IS_TRUE", "MAY_BE_TRUE"]; + case "bool": + return ["_IS_BOOL", "MAY_BE_BOOL"]; + case "int": + return ["IS_LONG", "MAY_BE_LONG"]; + case "float": + return ["IS_DOUBLE", "MAY_BE_DOUBLE"]; + case "string": + return ["IS_STRING", "MAY_BE_STRING"]; + case "array": + return ["IS_ARRAY", "MAY_BE_ARRAY"]; + case "object": + return ["IS_OBJECT", "MAY_BE_OBJECT"]; + case "callable": + return ["IS_CALLABLE", "MAY_BE_CALLABLE"]; + case "mixed": + return ["IS_MIXED", "MAY_BE_ANY"]; + case "void": + return ["IS_VOID", "MAY_BE_VOID"]; + case "static": + return ["IS_STATIC", "MAY_BE_STATIC"]; + case "never": + return ["IS_NEVER", "MAY_BE_NEVER"]; default: throw new Exception("Not implemented: $this->name"); } } - public function toTypeMask(): string { - assert($this->isBuiltin); + public function toTypeCode(): string { + return $this->toTypeInfo()[0]; + } - switch ($this->name) { - case "null": - return "MAY_BE_NULL"; - case "false": - return "MAY_BE_FALSE"; - case "true": - return "MAY_BE_TRUE"; - case "bool": - return "MAY_BE_BOOL"; - case "int": - return "MAY_BE_LONG"; - case "float": - return "MAY_BE_DOUBLE"; - case "string": - return "MAY_BE_STRING"; - case "array": - return "MAY_BE_ARRAY"; - case "object": - return "MAY_BE_OBJECT"; - case "callable": - return "MAY_BE_CALLABLE"; - case "mixed": - return "MAY_BE_ANY"; - case "void": - return "MAY_BE_VOID"; - case "static": - return "MAY_BE_STATIC"; - case "never": - return "MAY_BE_NEVER"; - default: - throw new Exception("Not implemented: $this->name"); - } + public function toTypeMask(): string { + return $this->toTypeInfo()[1]; } public function toOptimizerTypeMaskForArrayKey(): string { @@ -898,13 +866,6 @@ interface VariableLikeName { abstract class AbstractConstName implements VariableLikeName { - public function equals(AbstractConstName $const): bool - { - return $this->__toString() === $const->__toString(); - } - - abstract public function isClassConst(): bool; - public function isUnknown(): bool { return strtolower($this->__toString()) === "unknown"; @@ -922,11 +883,6 @@ class ConstName extends AbstractConstName { $this->const = $const; } - public function isClassConst(): bool - { - return false; - } - public function isUnknown(): bool { $name = $this->__toString(); @@ -957,11 +913,6 @@ class ClassConstName extends AbstractConstName { $this->const = $const; } - public function isClassConst(): bool - { - return true; - } - public function __toString(): string { return $this->class->toString() . "::" . $this->const; @@ -1000,7 +951,6 @@ interface FunctionOrMethodName { public function getMethodSynopsisFilename(): string; public function getNameForAttributes(): string; public function __toString(): string; - public function isMethod(): bool; public function isConstructor(): bool; public function isDestructor(): bool; } @@ -1009,9 +959,6 @@ class FunctionName implements FunctionOrMethodName { private /* readonly */ Name $name; public function __construct(Name $name) { - if ($name->name === '_clone') { - $name = new Name('clone', $name->getAttributes()); - } $this->name = $name; } @@ -1063,10 +1010,6 @@ class FunctionName implements FunctionOrMethodName { return $this->name->toString(); } - public function isMethod(): bool { - return false; - } - public function isConstructor(): bool { return false; } @@ -1112,10 +1055,6 @@ class MethodName implements FunctionOrMethodName { return "$this->className::$this->methodName"; } - public function isMethod(): bool { - return true; - } - public function isConstructor(): bool { return $this->methodName === "__construct"; } @@ -1247,6 +1186,119 @@ class ReturnInfo { } } +class VersionFlags { + + /** + * Keys are the PHP versions, values are arrays of flags + */ + private array $flagsByVersion; + + public function __construct(array $baseFlags) { + $this->flagsByVersion = []; + foreach (ALL_PHP_VERSION_IDS as $version) { + $this->flagsByVersion[$version] = $baseFlags; + } + } + + public function addForVersionsAbove(string $flag, int $minimumVersionId): void { + $write = false; + + foreach (ALL_PHP_VERSION_IDS as $version) { + if ($version === $minimumVersionId || $write === true) { + $this->flagsByVersion[$version][] = $flag; + $write = true; + } + } + } + + public function isEmpty(): bool { + foreach (ALL_PHP_VERSION_IDS as $version) { + if ($this->flagsByVersion[$version] !== []) { + return false; + } + } + return true; + } + + public function generateVersionDependentFlagCode( + string $codeTemplate, + ?int $phpVersionIdMinimumCompatibility, + ?int $phpVersionIdMaxCompatibility = null + ): string { + $flagsByPhpVersions = $this->flagsByVersion; + $phpVersions = ALL_PHP_VERSION_IDS; + sort($phpVersions); + $currentPhpVersion = end($phpVersions); + + // No version compatibility is needed + if ($phpVersionIdMinimumCompatibility === null) { + if (empty($flagsByPhpVersions[$currentPhpVersion])) { + return ''; + } + return sprintf($codeTemplate, implode("|", $flagsByPhpVersions[$currentPhpVersion])); + } + + ksort($flagsByPhpVersions); + // Remove flags which depend on a PHP version below the minimally supported one + $index = array_search($phpVersionIdMinimumCompatibility, array_keys($flagsByPhpVersions)); + if ($index === false) { + throw new Exception("Missing version dependent flags for PHP version ID \"$phpVersionIdMinimumCompatibility\""); + } + $flagsByPhpVersions = array_slice($flagsByPhpVersions, $index, null, true); + if ($phpVersionIdMaxCompatibility !== null) { + // Remove flags which depend on a PHP version above the maximally supported one + $index = array_search($phpVersionIdMaxCompatibility, array_keys($flagsByPhpVersions)); + if ($index === false) { + throw new Exception("Missing version dependent flags for PHP version ID \"$phpVersionIdMaxCompatibility\""); + } + $flagsByPhpVersions = array_slice($flagsByPhpVersions, 0, $index, true); + } + + // Remove version-specific flags which don't differ from the previous one + // Also populate '0' values + $previousVersionId = null; + foreach ($flagsByPhpVersions as $versionId => $versionFlags) { + if ($versionFlags === []) { + $versionFlags = ['0']; + $flagsByPhpVersions[$versionId] = ['0']; + } + if ($previousVersionId !== null && $flagsByPhpVersions[$previousVersionId] === $versionFlags) { + unset($flagsByPhpVersions[$versionId]); + } else { + $previousVersionId = $versionId; + } + } + + $flagCount = count($flagsByPhpVersions); + + // Do not add a condition unnecessarily when the only version is the same as the minimally supported one + if ($flagCount === 1) { + reset($flagsByPhpVersions); + $firstVersion = key($flagsByPhpVersions); + if ($firstVersion === $phpVersionIdMinimumCompatibility) { + return sprintf($codeTemplate, implode("|", reset($flagsByPhpVersions))); + } + } + + // Add the necessary conditions around the code using the version-specific flags + $code = ''; + $i = 0; + foreach (array_reverse($flagsByPhpVersions, true) as $version => $versionFlags) { + $if = $i === 0 ? "#if" : "#elif"; + $endif = $i === $flagCount - 1 ? "#endif\n" : ""; + + $code .= "$if (PHP_VERSION_ID >= $version)\n"; + + $code .= sprintf($codeTemplate, implode("|", $versionFlags)); + $code .= $endif; + + $i++; + } + + return $code; + } +} + class FuncInfo { public /* readonly */ FunctionOrMethodName $name; private /* readonly */ int $classFlags; @@ -1317,10 +1369,10 @@ class FuncInfo { public function isMethod(): bool { - return $this->name->isMethod(); + return $this->name instanceof MethodName; } - public function isFinalMethod(): bool + private function isFinalMethod(): bool { return ($this->flags & Modifiers::FINAL) || ($this->classFlags & Modifiers::FINAL); } @@ -1331,7 +1383,7 @@ class FuncInfo { } /** @return string[] */ - public function getModifierNames(): array + private function getModifierNames(): array { if (!$this->isMethod()) { return []; @@ -1371,7 +1423,7 @@ class FuncInfo { return false; } - public function equalsApartFromNameAndRefcount(FuncInfo $other): bool { + private function equalsApartFromNameAndRefcount(FuncInfo $other): bool { if (count($this->args) !== count($other->args)) { return false; } @@ -1414,27 +1466,21 @@ class FuncInfo { return null; } - $php84MinimumCompatibility = $this->minimumPhpVersionIdCompatibility === null || $this->minimumPhpVersionIdCompatibility >= PHP_84_VERSION_ID; - $code = ''; - - if (!$php84MinimumCompatibility) { - $code .= "#if (PHP_VERSION_ID >= " . PHP_84_VERSION_ID . ")\n"; - } - + $infos = ''; foreach ($this->framelessFunctionInfos as $framelessFunctionInfo) { $code .= "ZEND_FRAMELESS_FUNCTION({$this->name->getFunctionName()}, {$framelessFunctionInfo->arity});\n"; + $infos .= "\t{ ZEND_FRAMELESS_FUNCTION_NAME({$this->name->getFunctionName()}, {$framelessFunctionInfo->arity}), {$framelessFunctionInfo->arity} },\n"; } $code .= 'static const zend_frameless_function_info ' . $this->getFramelessFunctionInfosName() . "[] = {\n"; - foreach ($this->framelessFunctionInfos as $framelessFunctionInfo) { - $code .= "\t{ ZEND_FRAMELESS_FUNCTION_NAME({$this->name->getFunctionName()}, {$framelessFunctionInfo->arity}), {$framelessFunctionInfo->arity} },\n"; - } + $code .= $infos; $code .= "\t{ 0 },\n"; $code .= "};\n"; + $php84MinimumCompatibility = $this->minimumPhpVersionIdCompatibility === null || $this->minimumPhpVersionIdCompatibility >= PHP_84_VERSION_ID; if (!$php84MinimumCompatibility) { - $code .= "#endif\n"; + return "#if (PHP_VERSION_ID >= " . PHP_84_VERSION_ID . ")\n$code#endif\n"; } return $code; @@ -1445,14 +1491,6 @@ class FuncInfo { } public function getFunctionEntry(): string { - $code = ""; - - $php84MinimumCompatibility = $this->minimumPhpVersionIdCompatibility === null || $this->minimumPhpVersionIdCompatibility >= PHP_84_VERSION_ID; - $isVanillaEntry = $this->alias === null && !$this->supportsCompileTimeEval && $this->exposedDocComment === null && empty($this->framelessFunctionInfos); - $argInfoName = $this->getArgInfoName(); - $flagsByPhpVersions = $this->getArginfoFlagsByPhpVersions(); - $functionEntryCode = null; - if (!empty($this->framelessFunctionInfos)) { if ($this->isMethod()) { throw new Exception('Frameless methods are not supported yet'); @@ -1465,6 +1503,10 @@ class FuncInfo { } } + $isVanillaEntry = $this->alias === null && !$this->supportsCompileTimeEval && $this->exposedDocComment === null && empty($this->framelessFunctionInfos); + $argInfoName = $this->getArgInfoName(); + $flagsByPhpVersions = $this->getArginfoFlagsByPhpVersions(); + if ($this->isMethod()) { $zendName = '"' . $this->name->methodName . '"'; if ($this->alias) { @@ -1475,80 +1517,60 @@ class FuncInfo { } else { throw new Error("Cannot happen"); } + } elseif ($this->flags & Modifiers::ABSTRACT) { + $name = "NULL"; } else { - if ($this->flags & Modifiers::ABSTRACT) { - $name = "NULL"; - } else { - $name = "zim_" . $this->name->getDeclarationClassName() . "_" . $this->name->methodName; + $name = "zim_" . $this->name->getDeclarationClassName() . "_" . $this->name->methodName; - if ($isVanillaEntry) { - $template = "\tZEND_ME(" . $this->name->getDeclarationClassName() . ", " . $this->name->methodName . ", $argInfoName, %s)\n"; - $flagsCode = generateVersionDependentFlagCode( - $template, - $flagsByPhpVersions, - $this->minimumPhpVersionIdCompatibility - ); - $functionEntryCode = rtrim($flagsCode); - } + if ($isVanillaEntry) { + $template = "\tZEND_ME(" . $this->name->getDeclarationClassName() . ", " . $this->name->methodName . ", $argInfoName, %s)\n"; + $flagsCode = $flagsByPhpVersions->generateVersionDependentFlagCode( + $template, + $this->minimumPhpVersionIdCompatibility + ); + return rtrim($flagsCode) . "\n"; } } } else if ($this->name instanceof FunctionName) { $functionName = $this->name->getFunctionName(); $declarationName = $this->alias ? $this->alias->getNonNamespacedName() : $this->name->getDeclarationName(); + $name = "zif_$declarationName"; if ($this->name->getNamespace()) { $namespace = addslashes($this->name->getNamespace()); $zendName = "ZEND_NS_NAME(\"$namespace\", \"$functionName\")"; - $name = "zif_$declarationName"; } else { - $zendName = '"' . $functionName . '"'; - $name = "zif_$declarationName"; - // Can only use ZEND_FE() if we have no flags for *all* versions - $hasFlags = false; - foreach ($flagsByPhpVersions as $flags) { - if ($flags !== ['0']) { - $hasFlags = true; - break; - } - } - if ($isVanillaEntry && !$hasFlags) { - $functionEntryCode = "\tZEND_FE($declarationName, $argInfoName)"; + if ($isVanillaEntry && $flagsByPhpVersions->isEmpty()) { + return "\tZEND_FE($declarationName, $argInfoName)\n"; } + $zendName = '"' . $functionName . '"'; } } else { throw new Error("Cannot happen"); } - if ($functionEntryCode !== null) { - $code .= "$functionEntryCode\n"; - } else { - if (!$php84MinimumCompatibility) { - $code .= "#if (PHP_VERSION_ID >= " . PHP_84_VERSION_ID . ")\n"; - } + $docComment = $this->exposedDocComment ? '"' . $this->exposedDocComment->escape() . '"' : "NULL"; + $framelessFuncInfosName = !empty($this->framelessFunctionInfos) ? $this->getFramelessFunctionInfosName() : "NULL"; - $php84AndAboveFlags = array_slice($flagsByPhpVersions, 5, null, true); - $docComment = $this->exposedDocComment ? '"' . $this->exposedDocComment->escape() . '"' : "NULL"; - $framelessFuncInfosName = !empty($this->framelessFunctionInfos) ? $this->getFramelessFunctionInfosName() : "NULL"; + // Assume 8.4+ here, if older versions are supported this is conditional + $code = $flagsByPhpVersions->generateVersionDependentFlagCode( + "\tZEND_RAW_FENTRY($zendName, $name, $argInfoName, %s, $framelessFuncInfosName, $docComment)\n", + PHP_84_VERSION_ID + ); - $code .= generateVersionDependentFlagCode( - "\tZEND_RAW_FENTRY($zendName, $name, $argInfoName, %s, $framelessFuncInfosName, $docComment)\n", - $php84AndAboveFlags, - PHP_84_VERSION_ID + $php84MinimumCompatibility = $this->minimumPhpVersionIdCompatibility === null || $this->minimumPhpVersionIdCompatibility >= PHP_84_VERSION_ID; + if (!$php84MinimumCompatibility) { + $code = "#if (PHP_VERSION_ID >= " . PHP_84_VERSION_ID . ")\n$code"; + $code .= "#else\n"; + + $code .= $flagsByPhpVersions->generateVersionDependentFlagCode( + "\tZEND_RAW_FENTRY($zendName, $name, $argInfoName, %s)\n", + $this->minimumPhpVersionIdCompatibility, + PHP_83_VERSION_ID ); - if (!$php84MinimumCompatibility) { - $code .= "#else\n"; - - $flags = array_slice($flagsByPhpVersions, 0, 4, true); - $code .= generateVersionDependentFlagCode( - "\tZEND_RAW_FENTRY($zendName, $name, $argInfoName, %s)\n", - $flags, - $this->minimumPhpVersionIdCompatibility - ); - - $code .= "#endif\n"; - } + $code .= "#endif\n"; } return $code; @@ -1589,8 +1611,7 @@ class FuncInfo { $this->minimumPhpVersionIdCompatibility = $minimumPhpVersionIdCompatibility; } - /** @return array */ - private function getArginfoFlagsByPhpVersions(): array + private function getArginfoFlagsByPhpVersions(): VersionFlags { $flags = []; @@ -1628,39 +1649,21 @@ class FuncInfo { } } - $php82AndAboveFlags = $flags; + $flags = new VersionFlags($flags); + if ($this->isMethod() === false && $this->supportsCompileTimeEval) { - $php82AndAboveFlags[] = "ZEND_ACC_COMPILE_TIME_EVAL"; + $flags->addForVersionsAbove("ZEND_ACC_COMPILE_TIME_EVAL", PHP_82_VERSION_ID); } - $php85AndAboveFlags = $php82AndAboveFlags; foreach ($this->attributes as $attr) { switch ($attr->class) { case "NoDiscard": - $php85AndAboveFlags[] = "ZEND_ACC_NODISCARD"; + $flags->addForVersionsAbove("ZEND_ACC_NODISCARD", PHP_85_VERSION_ID); break; } } - if (empty($flags)) { - $flags[] = "0"; - } - if (empty($php82AndAboveFlags)) { - $php82AndAboveFlags[] = "0"; - } - if (empty($php85AndAboveFlags)) { - $php85AndAboveFlags[] = "0"; - } - - return [ - PHP_70_VERSION_ID => $flags, - PHP_80_VERSION_ID => $flags, - PHP_81_VERSION_ID => $flags, - PHP_82_VERSION_ID => $php82AndAboveFlags, - PHP_83_VERSION_ID => $php82AndAboveFlags, - PHP_84_VERSION_ID => $php82AndAboveFlags, - PHP_85_VERSION_ID => $php85AndAboveFlags, - ]; + return $flags; } private function generateRefSect1(DOMDocument $doc, string $role): DOMElement { @@ -2358,11 +2361,14 @@ class EvaluatedValue $this->isUnknownConstValue = $isUnknownConstValue; } - public function initializeZval(string $zvalName): string + public function initializeZval(string $zvalName, bool $alreadyExists = false, string $forStringDef = ''): string { $cExpr = $this->getCExpr(); - $code = "\tzval $zvalName;\n"; + $code = ''; + if (!$alreadyExists) { + $code = "\tzval $zvalName;\n"; + } if ($this->type->isNull()) { $code .= "\tZVAL_NULL(&$zvalName);\n"; @@ -2382,8 +2388,11 @@ class EvaluatedValue if ($cExpr === '""') { $code .= "\tZVAL_EMPTY_STRING(&$zvalName);\n"; } else { - $code .= "\tzend_string *{$zvalName}_str = zend_string_init($cExpr, strlen($cExpr), 1);\n"; - $code .= "\tZVAL_STR(&$zvalName, {$zvalName}_str);\n"; + if ($forStringDef === '') { + $forStringDef = "{$zvalName}_str"; + } + $code .= "\tzend_string *$forStringDef = zend_string_init($cExpr, strlen($cExpr), 1);\n"; + $code .= "\tZVAL_STR(&$zvalName, $forStringDef);\n"; } } elseif ($this->type->isArray()) { if ($cExpr == '[]') { @@ -2454,10 +2463,7 @@ abstract class VariableLike abstract public function discardInfoForOldPhpVersions(?int $minimumPhpVersionIdCompatibility): void; - /** - * @return array - */ - protected function getFlagsByPhpVersion(): array + protected function getFlagsByPhpVersion(): VersionFlags { $flags = "ZEND_ACC_PUBLIC"; if ($this->flags & Modifiers::PROTECTED) { @@ -2466,15 +2472,7 @@ abstract class VariableLike $flags = "ZEND_ACC_PRIVATE"; } - return [ - PHP_70_VERSION_ID => [$flags], - PHP_80_VERSION_ID => [$flags], - PHP_81_VERSION_ID => [$flags], - PHP_82_VERSION_ID => [$flags], - PHP_83_VERSION_ID => [$flags], - PHP_84_VERSION_ID => [$flags], - PHP_85_VERSION_ID => [$flags], - ]; + return new VersionFlags([$flags]); } protected function getTypeCode(string $variableLikeName, string &$code): string @@ -2575,23 +2573,6 @@ abstract class VariableLike } } - /** - * @param array $flags - * @return array - */ - protected function addFlagForVersionsAbove(array $flags, string $flag, int $minimumVersionId): array - { - $write = false; - - foreach ($flags as $version => $versionFlags) { - if ($version === $minimumVersionId || $write === true) { - $flags[$version][] = $flag; - $write = true; - } - } - - return $flags; - } } class ConstInfo extends VariableLike @@ -2688,41 +2669,35 @@ class ConstInfo extends VariableLike return $this->valueString; } - public function getPredefinedConstantTerm(DOMDocument $doc, int $indentationLevel): DOMElement { + private function getPredefinedConstantElement( + DOMDocument $doc, + int $indentationLevel, + string $name + ): DOMElement { $indentation = str_repeat(" ", $indentationLevel); - $termElement = $doc->createElement("term"); + $element = $doc->createElement($name); $constantElement = $doc->createElement("constant"); $constantElement->textContent = $this->name->__toString(); $typeElement = ($this->phpDocType ?? $this->type)->getTypeForDoc($doc); - $termElement->appendChild(new DOMText("\n$indentation ")); - $termElement->appendChild($constantElement); - $termElement->appendChild(new DOMText("\n$indentation (")); - $termElement->appendChild($typeElement); - $termElement->appendChild(new DOMText(")\n$indentation")); + $element->appendChild(new DOMText("\n$indentation ")); + $element->appendChild($constantElement); + $element->appendChild(new DOMText("\n$indentation (")); + $element->appendChild($typeElement); + $element->appendChild(new DOMText(")\n$indentation")); - return $termElement; + return $element; + } + + public function getPredefinedConstantTerm(DOMDocument $doc, int $indentationLevel): DOMElement { + return $this->getPredefinedConstantElement($doc, $indentationLevel, "term"); } public function getPredefinedConstantEntry(DOMDocument $doc, int $indentationLevel): DOMElement { - $indentation = str_repeat(" ", $indentationLevel); - - $entryElement = $doc->createElement("entry"); - - $constantElement = $doc->createElement("constant"); - $constantElement->textContent = $this->name->__toString(); - $typeElement = ($this->phpDocType ?? $this->type)->getTypeForDoc($doc); - - $entryElement->appendChild(new DOMText("\n$indentation ")); - $entryElement->appendChild($constantElement); - $entryElement->appendChild(new DOMText("\n$indentation (")); - $entryElement->appendChild($typeElement); - $entryElement->appendChild(new DOMText(")\n$indentation")); - - return $entryElement; + return $this->getPredefinedConstantElement($doc, $indentationLevel, "entry"); } public function discardInfoForOldPhpVersions(?int $phpVersionIdMinimumCompatibility): void { @@ -2754,7 +2729,7 @@ class ConstInfo extends VariableLike // Condition will be added by generateCodeWithConditions() - if ($this->name->isClassConst()) { + if ($this->name instanceof ClassConstName) { $code = $this->getClassConstDeclaration($value, $allConstInfos); } else { $code = $this->getGlobalConstDeclaration($value); @@ -2821,7 +2796,8 @@ class ConstInfo extends VariableLike { $constName = $this->name->getDeclarationName(); - $zvalCode = $value->initializeZval("const_{$constName}_value", $allConstInfos); + // TODO $allConstInfos is unused + $zvalCode = $value->initializeZval("const_{$constName}_value"); $code = "\n" . $zvalCode; @@ -2852,9 +2828,8 @@ class ConstInfo extends VariableLike } $template .= "zend_declare_typed_class_constant(class_entry, $nameCode, &const_{$constName}_value, %s, $commentCode, $typeCode);\n"; - $code .= generateVersionDependentFlagCode( + $code .= $this->getFlagsByPhpVersion()->generateVersionDependentFlagCode( $template, - $this->getFlagsByPhpVersion(), $this->phpVersionIdMinimumCompatibility ); } @@ -2870,9 +2845,8 @@ class ConstInfo extends VariableLike $template = "\t"; } $template .= "zend_declare_class_constant_ex(class_entry, $nameCode, &const_{$constName}_value, %s, $commentCode);\n"; - $code .= generateVersionDependentFlagCode( + $code .= $this->getFlagsByPhpVersion()->generateVersionDependentFlagCode( $template, - $this->getFlagsByPhpVersion(), $this->phpVersionIdMinimumCompatibility ); } @@ -2922,20 +2896,17 @@ class ConstInfo extends VariableLike throw new Exception("Unimplemented constant type"); } - /** - * @return array - */ - protected function getFlagsByPhpVersion(): array + protected function getFlagsByPhpVersion(): VersionFlags { $flags = parent::getFlagsByPhpVersion(); // $this->isDeprecated also accounts for any #[\Deprecated] attributes if ($this->isDeprecated) { - $flags = $this->addFlagForVersionsAbove($flags, "ZEND_ACC_DEPRECATED", PHP_80_VERSION_ID); + $flags->addForVersionsAbove("ZEND_ACC_DEPRECATED", PHP_80_VERSION_ID); } if ($this->flags & Modifiers::FINAL) { - $flags = $this->addFlagForVersionsAbove($flags, "ZEND_ACC_FINAL", PHP_81_VERSION_ID); + $flags->addForVersionsAbove("ZEND_ACC_FINAL", PHP_81_VERSION_ID); } return $flags; @@ -3250,9 +3221,8 @@ class PropertyInfo extends VariableLike $template .= "zend_declare_property_ex(class_entry, $nameCode, &$zvalName, %s, $commentCode);\n"; } - $code .= generateVersionDependentFlagCode( + $code .= $this->getFlagsByPhpVersion()->generateVersionDependentFlagCode( $template, - $this->getFlagsByPhpVersion(), $this->phpVersionIdMinimumCompatibility ); @@ -3261,29 +3231,26 @@ class PropertyInfo extends VariableLike return $code; } - /** - * @return array - */ - protected function getFlagsByPhpVersion(): array + protected function getFlagsByPhpVersion(): VersionFlags { $flags = parent::getFlagsByPhpVersion(); if ($this->flags & Modifiers::STATIC) { - $flags = $this->addFlagForVersionsAbove($flags, "ZEND_ACC_STATIC", PHP_70_VERSION_ID); + $flags->addForVersionsAbove("ZEND_ACC_STATIC", PHP_70_VERSION_ID); } if ($this->flags & Modifiers::FINAL) { - $flags = $this->addFlagForVersionsAbove($flags, "ZEND_ACC_FINAL", PHP_84_VERSION_ID); + $flags->addForVersionsAbove("ZEND_ACC_FINAL", PHP_84_VERSION_ID); } if ($this->flags & Modifiers::READONLY) { - $flags = $this->addFlagForVersionsAbove($flags, "ZEND_ACC_READONLY", PHP_81_VERSION_ID); + $flags->addForVersionsAbove("ZEND_ACC_READONLY", PHP_81_VERSION_ID); } elseif ($this->classFlags & Modifiers::READONLY) { - $flags = $this->addFlagForVersionsAbove($flags, "ZEND_ACC_READONLY", PHP_82_VERSION_ID); + $flags->addForVersionsAbove("ZEND_ACC_READONLY", PHP_82_VERSION_ID); } if ($this->isVirtual) { - $flags = $this->addFlagForVersionsAbove($flags, "ZEND_ACC_VIRTUAL", PHP_84_VERSION_ID); + $flags->addForVersionsAbove("ZEND_ACC_VIRTUAL", PHP_84_VERSION_ID); } return $flags; @@ -3349,8 +3316,12 @@ class AttributeInfo { $this->args = $args; } - /** @param array $allConstInfos */ - public function generateCode(string $invocation, string $nameSuffix, array $allConstInfos, ?int $phpVersionIdMinimumCompatibility): string { + /** + * @param array $allConstInfos + * @param array &$declaredStrings Map of string content to + * the name of a zend_string already created with that content + */ + public function generateCode(string $invocation, string $nameSuffix, array $allConstInfos, ?int $phpVersionIdMinimumCompatibility, array &$declaredStrings = []): string { $escapedAttributeName = strtr($this->class, '\\', '_'); [$stringInit, $nameCode, $stringRelease] = StringBuilder::getString( "attribute_name_{$escapedAttributeName}_$nameSuffix", @@ -3374,13 +3345,21 @@ class AttributeInfo { ); if ($strInit === '') { $initValue = "\tZVAL_STR(&attribute_{$escapedAttributeName}_{$nameSuffix}->args[$i].value, $strUse);\n"; + } elseif (isset($declaredStrings[$strVal])) { + $strUse = $declaredStrings[$strVal]; + $initValue = "\tZVAL_STR_COPY(&attribute_{$escapedAttributeName}_{$nameSuffix}->args[$i].value, $strUse);\n"; } } if ($initValue === '') { $value = EvaluatedValue::createFromExpression($arg->value, null, null, $allConstInfos); - $zvalName = "attribute_{$escapedAttributeName}_{$nameSuffix}_arg$i"; - $code .= $value->initializeZval($zvalName); - $code .= "\tZVAL_COPY_VALUE(&attribute_{$escapedAttributeName}_{$nameSuffix}->args[$i].value, &$zvalName);\n"; + $code .= $value->initializeZval( + "attribute_{$escapedAttributeName}_{$nameSuffix}->args[$i].value", + true, + "attribute_{$escapedAttributeName}_{$nameSuffix}_arg{$i}_str" + ); + if ($arg->value instanceof Node\Scalar\String_) { + $declaredStrings[$arg->value->value] = "attribute_{$escapedAttributeName}_{$nameSuffix}_arg{$i}_str"; + } } else { $code .= $initValue; } @@ -3529,13 +3508,17 @@ class ClassInfo { $code .= "{\n"; + $flags = $this->getFlagsByPhpVersion(); + $classMethods = ($this->funcInfos === []) ? 'NULL' : "class_{$escapedName}_methods"; if ($this->type === "enum") { $name = addslashes((string) $this->name); $backingType = $this->enumBackingType ? $this->enumBackingType->toTypeCode() : "IS_UNDEF"; $code .= "\tzend_class_entry *class_entry = zend_register_internal_enum(\"$name\", $backingType, $classMethods);\n"; - $code .= generateVersionDependentFlagCode("\tclass_entry->ce_flags = %s;\n", $this->getFlagsByPhpVersion(), $this->phpVersionIdMinimumCompatibility); + if (!$flags->isEmpty()) { + $code .= $this->getFlagsByPhpVersion()->generateVersionDependentFlagCode("\tclass_entry->ce_flags = %s;\n", $this->phpVersionIdMinimumCompatibility); + } } else { $code .= "\tzend_class_entry ce, *class_entry;\n\n"; if (count($this->name->getParts()) > 1) { @@ -3553,7 +3536,7 @@ class ClassInfo { } $template = "\tclass_entry = zend_register_internal_class_with_flags(&ce, " . (isset($this->extends[0]) ? "class_entry_" . str_replace("\\", "_", $this->extends[0]->toString()) : "NULL") . ", %s);\n"; - $entries = generateVersionDependentFlagCode($template, $this->getFlagsByPhpVersion(), $this->phpVersionIdMinimumCompatibility ? max($this->phpVersionIdMinimumCompatibility, PHP_84_VERSION_ID) : null); + $entries = $flags->generateVersionDependentFlagCode($template, $this->phpVersionIdMinimumCompatibility ? max($this->phpVersionIdMinimumCompatibility, PHP_84_VERSION_ID) : null); if ($entries !== '') { $code .= $entries; } else { @@ -3564,12 +3547,16 @@ class ClassInfo { $code .= "#else\n"; $code .= "\tclass_entry = zend_register_internal_class_ex(&ce, " . (isset($this->extends[0]) ? "class_entry_" . str_replace("\\", "_", $this->extends[0]->toString()) : "NULL") . ");\n"; - $code .= generateVersionDependentFlagCode("\tclass_entry->ce_flags |= %s;\n", $this->getFlagsByPhpVersion(), $this->phpVersionIdMinimumCompatibility); + if (!$flags->isEmpty()) { + $code .= $flags->generateVersionDependentFlagCode("\tclass_entry->ce_flags |= %s;\n", $this->phpVersionIdMinimumCompatibility); + } $code .= "#endif\n"; } } else { $code .= "\tclass_entry = zend_register_internal_interface(&ce);\n"; - $code .= generateVersionDependentFlagCode("\tclass_entry->ce_flags |= %s;\n", $this->getFlagsByPhpVersion(), $this->phpVersionIdMinimumCompatibility); + if (!$flags->isEmpty()) { + $code .= $flags->generateVersionDependentFlagCode("\tclass_entry->ce_flags |= %s;\n", $this->phpVersionIdMinimumCompatibility); + } } } @@ -3614,60 +3601,49 @@ class ClassInfo { foreach ($this->propertyInfos as $property) { $code .= $property->getDeclaration($allConstInfos); } + // Reusable strings for wrapping conditional PHP 8.0+ code + if ($php80MinimumCompatibility) { + $php80CondStart = ''; + $php80CondEnd = ''; + } else { + $php80CondStart = "\n#if (PHP_VERSION_ID >= " . PHP_80_VERSION_ID . ")"; + $php80CondEnd = "#endif\n"; + } + + $declaredStrings = []; if (!empty($this->attributes)) { - if (!$php80MinimumCompatibility) { - $code .= "\n#if (PHP_VERSION_ID >= " . PHP_80_VERSION_ID . ")"; - } + $code .= $php80CondStart; foreach ($this->attributes as $key => $attribute) { $code .= $attribute->generateCode( "zend_add_class_attribute(class_entry", "class_{$escapedName}_$key", $allConstInfos, - $this->phpVersionIdMinimumCompatibility + $this->phpVersionIdMinimumCompatibility, + $declaredStrings ); } - if (!$php80MinimumCompatibility) { - $code .= "#endif\n"; - } + $code .= $php80CondEnd; } - if ($attributeInitializationCode = generateConstantAttributeInitialization($this->constInfos, $allConstInfos, $this->phpVersionIdMinimumCompatibility, $this->cond)) { - if (!$php80MinimumCompatibility) { - $code .= "#if (PHP_VERSION_ID >= " . PHP_80_VERSION_ID . ")"; - } - + if ($attributeInitializationCode = generateConstantAttributeInitialization($this->constInfos, $allConstInfos, $this->phpVersionIdMinimumCompatibility, $this->cond, $declaredStrings)) { + $code .= $php80CondStart; $code .= "\n" . $attributeInitializationCode; - - if (!$php80MinimumCompatibility) { - $code .= "#endif\n"; - } + $code .= $php80CondEnd; } - if ($attributeInitializationCode = generatePropertyAttributeInitialization($this->propertyInfos, $allConstInfos, $this->phpVersionIdMinimumCompatibility)) { - if (!$php80MinimumCompatibility) { - $code .= "#if (PHP_VERSION_ID >= " . PHP_80_VERSION_ID . ")"; - } - + if ($attributeInitializationCode = generatePropertyAttributeInitialization($this->propertyInfos, $allConstInfos, $this->phpVersionIdMinimumCompatibility, $declaredStrings)) { + $code .= $php80CondStart; $code .= "\n" . $attributeInitializationCode; - - if (!$php80MinimumCompatibility) { - $code .= "#endif\n"; - } + $code .= $php80CondEnd; } - if ($attributeInitializationCode = generateFunctionAttributeInitialization($this->funcInfos, $allConstInfos, $this->phpVersionIdMinimumCompatibility, $this->cond)) { - if (!$php80MinimumCompatibility) { - $code .= "#if (PHP_VERSION_ID >= " . PHP_80_VERSION_ID . ")\n"; - } - + if ($attributeInitializationCode = generateFunctionAttributeInitialization($this->funcInfos, $allConstInfos, $this->phpVersionIdMinimumCompatibility, $this->cond, $declaredStrings)) { + $code .= $php80CondStart; $code .= "\n" . $attributeInitializationCode; - - if (!$php80MinimumCompatibility) { - $code .= "#endif\n"; - } + $code .= $php80CondEnd; } $code .= "\n\treturn class_entry;\n"; @@ -3685,10 +3661,7 @@ class ClassInfo { return $code; } - /** - * @return array - */ - private function getFlagsByPhpVersion(): array + private function getFlagsByPhpVersion(): VersionFlags { $php70Flags = []; @@ -3708,44 +3681,28 @@ class ClassInfo { $php70Flags[] = "ZEND_ACC_DEPRECATED"; } - $php80Flags = $php70Flags; + $flags = new VersionFlags($php70Flags); if ($this->isStrictProperties) { - $php80Flags[] = "ZEND_ACC_NO_DYNAMIC_PROPERTIES"; + $flags->addForVersionsAbove("ZEND_ACC_NO_DYNAMIC_PROPERTIES", PHP_80_VERSION_ID); } - $php81Flags = $php80Flags; - if ($this->isNotSerializable) { - $php81Flags[] = "ZEND_ACC_NOT_SERIALIZABLE"; + $flags->addForVersionsAbove("ZEND_ACC_NOT_SERIALIZABLE", PHP_81_VERSION_ID); } - $php82Flags = $php81Flags; - if ($this->flags & Modifiers::READONLY) { - $php82Flags[] = "ZEND_ACC_READONLY_CLASS"; + $flags->addForVersionsAbove("ZEND_ACC_READONLY_CLASS", PHP_82_VERSION_ID); } foreach ($this->attributes as $attr) { if ($attr->class === "AllowDynamicProperties") { - $php82Flags[] = "ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES"; + $flags->addForVersionsAbove("ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES", PHP_82_VERSION_ID); break; } } - $php83Flags = $php82Flags; - $php84Flags = $php83Flags; - $php85Flags = $php84Flags; - - return [ - PHP_70_VERSION_ID => $php70Flags, - PHP_80_VERSION_ID => $php80Flags, - PHP_81_VERSION_ID => $php81Flags, - PHP_82_VERSION_ID => $php82Flags, - PHP_83_VERSION_ID => $php83Flags, - PHP_84_VERSION_ID => $php84Flags, - PHP_85_VERSION_ID => $php85Flags, - ]; + return $flags; } public function discardInfoForOldPhpVersions(?int $phpVersionIdMinimumCompatibility): void { @@ -4357,13 +4314,25 @@ class FileInfo { $stmts = $parser->parse($code); $nodeTraverser->traverse($stmts); - $fileTags = DocCommentTag::parseDocComments(getFileDocComments($stmts)); + $fileTags = DocCommentTag::parseDocComments(self::getFileDocComments($stmts)); $fileInfo = new FileInfo($fileTags); $fileInfo->handleStatements($stmts, $prettyPrinter); return $fileInfo; } + /** @return DocComment[] */ + private static function getFileDocComments(array $stmts): array { + if (empty($stmts)) { + return []; + } + + return array_filter( + $stmts[0]->getComments(), + static fn ($comment): bool => $comment instanceof DocComment + ); + } + private function handleStatements(array $stmts, PrettyPrinterAbstract $prettyPrinter): void { $conds = []; foreach ($stmts as $stmt) { @@ -4535,6 +4504,17 @@ class FileInfo { return empty($conds) ? null : implode(' && ', $conds); } + + /** @param array $allConstInfos */ + public function generateClassEntryCode(array $allConstInfos): string { + $code = ""; + + foreach ($this->classInfos as $class) { + $code .= "\n" . $class->getRegistration($allConstInfos); + } + + return $code; + } } class DocCommentTag { @@ -5088,18 +5068,6 @@ function parseClass( ); } -/** @return DocComment[] */ -function getFileDocComments(array $stmts): array { - if (empty($stmts)) { - return []; - } - - return array_filter( - $stmts[0]->getComments(), - static fn ( $comment ): bool => $comment instanceof DocComment - ); -} - /** * @template T * @param iterable $infos @@ -5227,8 +5195,9 @@ function generateArgInfoCode( $php80MinimumCompatibility = $fileInfo->getMinimumPhpVersionIdCompatibility() === null || $fileInfo->getMinimumPhpVersionIdCompatibility() >= PHP_80_VERSION_ID; if ($fileInfo->generateClassEntries) { - $attributeInitializationCode = generateFunctionAttributeInitialization($fileInfo->funcInfos, $allConstInfos, $fileInfo->getMinimumPhpVersionIdCompatibility(), null); - $attributeInitializationCode .= generateGlobalConstantAttributeInitialization($fileInfo->constInfos, $allConstInfos, $fileInfo->getMinimumPhpVersionIdCompatibility(), null); + $declaredStrings = []; + $attributeInitializationCode = generateFunctionAttributeInitialization($fileInfo->funcInfos, $allConstInfos, $fileInfo->getMinimumPhpVersionIdCompatibility(), null, $declaredStrings); + $attributeInitializationCode .= generateGlobalConstantAttributeInitialization($fileInfo->constInfos, $allConstInfos, $fileInfo->getMinimumPhpVersionIdCompatibility(), null, $declaredStrings); if ($attributeInitializationCode) { if (!$php80MinimumCompatibility) { $attributeInitializationCode = "\n#if (PHP_VERSION_ID >= " . PHP_80_VERSION_ID . ")" . $attributeInitializationCode . "#endif\n"; @@ -5253,18 +5222,7 @@ function generateArgInfoCode( $code .= "}\n"; } - $code .= generateClassEntryCode($fileInfo, $allConstInfos); - } - - return $code; -} - -/** @param array $allConstInfos */ -function generateClassEntryCode(FileInfo $fileInfo, array $allConstInfos): string { - $code = ""; - - foreach ($fileInfo->classInfos as $class) { - $code .= "\n" . $class->getRegistration($allConstInfos); + $code .= $fileInfo->generateClassEntryCode($allConstInfos); } return $code; @@ -5277,19 +5235,13 @@ function generateFunctionEntries(?Name $className, array $funcInfos, ?string $co return ''; } - $code = "\n"; - - if ($cond) { - $code .= "#if {$cond}\n"; - } - $functionEntryName = "ext_functions"; if ($className) { $underscoreName = implode("_", $className->getParts()); $functionEntryName = "class_{$underscoreName}_methods"; } - $code .= "static const zend_function_entry {$functionEntryName}[] = {\n"; + $code = "\nstatic const zend_function_entry {$functionEntryName}[] = {\n"; $code .= generateCodeWithConditions($funcInfos, "", static function (FuncInfo $funcInfo) { return $funcInfo->getFunctionEntry(); }, $cond); @@ -5297,18 +5249,22 @@ function generateFunctionEntries(?Name $className, array $funcInfos, ?string $co $code .= "};\n"; if ($cond) { - $code .= "#endif\n"; + $code = "\n#if {$cond}{$code}#endif\n"; } return $code; } -/** @param iterable $funcInfos */ -function generateFunctionAttributeInitialization(iterable $funcInfos, array $allConstInfos, ?int $phpVersionIdMinimumCompatibility, ?string $parentCond = null): string { +/** + * @param iterable $funcInfos + * @param array &$declaredStrings Map of string content to + * the name of a zend_string already created with that content + */ +function generateFunctionAttributeInitialization(iterable $funcInfos, array $allConstInfos, ?int $phpVersionIdMinimumCompatibility, ?string $parentCond = null, array &$declaredStrings = []): string { return generateCodeWithConditions( $funcInfos, "", - static function (FuncInfo $funcInfo) use ($allConstInfos, $phpVersionIdMinimumCompatibility) { + static function (FuncInfo $funcInfo) use ($allConstInfos, $phpVersionIdMinimumCompatibility, &$declaredStrings) { $code = null; if ($funcInfo->name instanceof MethodName) { @@ -5317,12 +5273,22 @@ function generateFunctionAttributeInitialization(iterable $funcInfos, array $all $functionTable = "CG(function_table)"; } + // Make sure we don't try and use strings that might only be + // conditionally available; string reuse is only among declarations + // that are always there + if ($funcInfo->cond) { + $useDeclared = []; + } else { + $useDeclared = &$declaredStrings; + } + foreach ($funcInfo->attributes as $key => $attribute) { $code .= $attribute->generateCode( "zend_add_function_attribute(zend_hash_str_find_ptr($functionTable, \"" . $funcInfo->name->getNameForAttributes() . "\", sizeof(\"" . $funcInfo->name->getNameForAttributes() . "\") - 1)", "func_" . $funcInfo->name->getNameForAttributes() . "_$key", $allConstInfos, - $phpVersionIdMinimumCompatibility + $phpVersionIdMinimumCompatibility, + $useDeclared ); } @@ -5332,7 +5298,8 @@ function generateFunctionAttributeInitialization(iterable $funcInfos, array $all "zend_add_parameter_attribute(zend_hash_str_find_ptr($functionTable, \"" . $funcInfo->name->getNameForAttributes() . "\", sizeof(\"" . $funcInfo->name->getNameForAttributes() . "\") - 1), $index", "func_{$funcInfo->name->getNameForAttributes()}_arg{$index}_$key", $allConstInfos, - $phpVersionIdMinimumCompatibility + $phpVersionIdMinimumCompatibility, + $useDeclared ); } } @@ -5346,12 +5313,15 @@ function generateFunctionAttributeInitialization(iterable $funcInfos, array $all /** * @param iterable $constInfos * @param array $allConstInfos + * @param array &$declaredStrings Map of string content to + * the name of a zend_string already created with that content */ function generateGlobalConstantAttributeInitialization( iterable $constInfos, array $allConstInfos, ?int $phpVersionIdMinimumCompatibility, - ?string $parentCond = null + ?string $parentCond = null, + array &$declaredStrings = [] ): string { $isConditional = false; if ($phpVersionIdMinimumCompatibility !== null && $phpVersionIdMinimumCompatibility < PHP_85_VERSION_ID) { @@ -5360,12 +5330,20 @@ function generateGlobalConstantAttributeInitialization( $code = generateCodeWithConditions( $constInfos, "", - static function (ConstInfo $constInfo) use ($allConstInfos, $isConditional) { + static function (ConstInfo $constInfo) use ($allConstInfos, $isConditional, &$declaredStrings) { $code = ""; if ($constInfo->attributes === []) { return null; } + // Make sure we don't try and use strings that might only be + // conditionally available; string reuse is only among declarations + // that are always there + if ($constInfo->cond) { + $useDeclared = []; + } else { + $useDeclared = &$declaredStrings; + } $constName = str_replace('\\', '\\\\', $constInfo->name->__toString()); $constVarName = 'const_' . $constName; @@ -5380,7 +5358,8 @@ function generateGlobalConstantAttributeInitialization( "zend_add_global_constant_attribute($constVarName", $constVarName . "_$key", $allConstInfos, - PHP_85_VERSION_ID + PHP_85_VERSION_ID, + $useDeclared ); } @@ -5397,25 +5376,37 @@ function generateGlobalConstantAttributeInitialization( /** * @param iterable $constInfos * @param array $allConstInfos + * @param array &$declaredStrings Map of string content to + * the name of a zend_string already created with that content */ function generateConstantAttributeInitialization( iterable $constInfos, array $allConstInfos, ?int $phpVersionIdMinimumCompatibility, - ?string $parentCond = null + ?string $parentCond = null, + array &$declaredStrings = [] ): string { return generateCodeWithConditions( $constInfos, "", - static function (ConstInfo $constInfo) use ($allConstInfos, $phpVersionIdMinimumCompatibility) { + static function (ConstInfo $constInfo) use ($allConstInfos, $phpVersionIdMinimumCompatibility, &$declaredStrings) { $code = null; + // Make sure we don't try and use strings that might only be + // conditionally available; string reuse is only among declarations + // that are always there + if ($constInfo->cond) { + $useDeclared = []; + } else { + $useDeclared = &$declaredStrings; + } foreach ($constInfo->attributes as $key => $attribute) { $code .= $attribute->generateCode( "zend_add_class_constant_attribute(class_entry, const_" . $constInfo->name->getDeclarationName(), "const_" . $constInfo->name->getDeclarationName() . "_$key", $allConstInfos, - $phpVersionIdMinimumCompatibility + $phpVersionIdMinimumCompatibility, + $useDeclared ); } @@ -5428,11 +5419,14 @@ function generateConstantAttributeInitialization( /** * @param iterable $propertyInfos * @param array $allConstInfos + * @param array &$declaredStrings Map of string content to + * the name of a zend_string already created with that content */ function generatePropertyAttributeInitialization( iterable $propertyInfos, array $allConstInfos, - ?int $phpVersionIdMinimumCompatibility + ?int $phpVersionIdMinimumCompatibility, + array &$declaredStrings ): string { $code = ""; foreach ($propertyInfos as $propertyInfo) { @@ -5441,7 +5435,8 @@ function generatePropertyAttributeInitialization( "zend_add_property_attribute(class_entry, property_" . $propertyInfo->name->getDeclarationName(), "property_" . $propertyInfo->name->getDeclarationName() . "_" . $key, $allConstInfos, - $phpVersionIdMinimumCompatibility + $phpVersionIdMinimumCompatibility, + $declaredStrings ); } } @@ -5464,80 +5459,6 @@ function generateOptimizerInfo(array $funcMap): string { return $code; } -/** - * @param array $flagsByPhpVersions - * @return string - */ -function generateVersionDependentFlagCode(string $codeTemplate, array $flagsByPhpVersions, ?int $phpVersionIdMinimumCompatibility): string -{ - $phpVersions = ALL_PHP_VERSION_IDS; - sort($phpVersions); - $currentPhpVersion = end($phpVersions); - - // No version compatibility is needed - if ($phpVersionIdMinimumCompatibility === null) { - if (empty($flagsByPhpVersions[$currentPhpVersion])) { - return ''; - } - - return sprintf($codeTemplate, implode("|", $flagsByPhpVersions[$currentPhpVersion])); - } - - // Remove flags which depend on a PHP version below the minimally supported one - ksort($flagsByPhpVersions); - $index = array_search($phpVersionIdMinimumCompatibility, array_keys($flagsByPhpVersions)); - if ($index === false) { - throw new Exception("Missing version dependent flags for PHP version ID \"$phpVersionIdMinimumCompatibility\""); - } - $flagsByPhpVersions = array_slice($flagsByPhpVersions, $index, null, true); - - // Remove empty version-specific flags - $flagsByPhpVersions = array_filter($flagsByPhpVersions); - - // There are no version-specific flags - if (empty($flagsByPhpVersions)) { - return ''; - } - - // Remove version-specific flags which don't differ from the previous one - $previousVersionId = null; - foreach ($flagsByPhpVersions as $versionId => $versionFlags) { - if ($previousVersionId !== null && $flagsByPhpVersions[$previousVersionId] === $versionFlags) { - unset($flagsByPhpVersions[$versionId]); - } else { - $previousVersionId = $versionId; - } - } - - $flagCount = count($flagsByPhpVersions); - - // Do not add a condition unnecessarily when the only version is the same as the minimally supported one - if ($flagCount === 1) { - reset($flagsByPhpVersions); - $firstVersion = key($flagsByPhpVersions); - if ($firstVersion === $phpVersionIdMinimumCompatibility) { - return sprintf($codeTemplate, implode("|", reset($flagsByPhpVersions))); - } - } - - // Add the necessary conditions around the code using the version-specific flags - $code = ''; - $i = 0; - foreach (array_reverse($flagsByPhpVersions, true) as $version => $versionFlags) { - $if = $i === 0 ? "#if" : "#elif"; - $endif = $i === $flagCount - 1 ? "#endif\n" : ""; - - $code .= "$if (PHP_VERSION_ID >= $version)\n"; - - $code .= sprintf($codeTemplate, implode("|", $versionFlags)); - $code .= $endif; - - $i++; - } - - return $code; -} - /** * @param array $constMap * @param array $undocumentedConstMap @@ -6135,7 +6056,7 @@ function initPhpParser() { } $isInitialized = true; - $version = "5.5.0"; + $version = "5.6.0"; $phpParserDir = __DIR__ . "/PHP-Parser-$version"; if (!is_dir($phpParserDir)) { installPhpParser($version, $phpParserDir); @@ -6429,7 +6350,7 @@ if ($generateOptimizerInfo) { if ($verifyManual) { foreach ($undocumentedConstMap as $constName => $info) { - if ($info->name->isClassConst() || $info->isUndocumentable) { + if ($info->name instanceof ClassConstName || $info->isUndocumentable) { continue; } diff --git a/docs/release-process.md b/docs/release-process.md index 37cf04dd705..08b95df5351 100644 --- a/docs/release-process.md +++ b/docs/release-process.md @@ -219,7 +219,7 @@ slightly different steps. We'll call attention where the steps differ. # With ZTS make distclean || \ ./buildconf --force \ - && ./configure --enable-zts --disable-all --enable-debug --enable-opcache --enable-opcache-jit \ + && ./configure --enable-zts --disable-all --enable-debug --enable-opcache-jit \ && make -j$(nproc) \ && make test TEST_PHP_ARGS="-q -j$(nproc)" \ || ./sapi/cli/php -v @@ -227,7 +227,7 @@ slightly different steps. We'll call attention where the steps differ. # Without ZTS make distclean || \ ./buildconf --force \ - && ./configure --disable-all --enable-debug --enable-opcache --enable-opcache-jit \ + && ./configure --disable-all --enable-debug --enable-opcache-jit \ && make -j$(nproc) \ && make test TEST_PHP_ARGS="-q -j$(nproc)" \ || ./sapi/cli/php -v @@ -500,9 +500,16 @@ slightly different steps. We'll call attention where the steps differ. > report any potential bugs that should be fixed before the upcoming GA > release. -5. 🔶 **For pre-GA *RCs* only,** coordinate with the social media team (i.e., - Derick) to post a tweet with the RC release announcement and link to the news - entry on php.net. ([@official_php](https://twitter.com/official_php)) +5. 🔶 **For alphas, betas, and *pre-GA* RCs,** coordinate with the + social media team (i.e., Derick and Sergey) to post a toot containing the + release announcement and link to the news entry on php.net. + You can send a PR to [toot-together](https://github.com/derickr/toot-together/) + with highlights from the NEWS file yourself, if you want. + + * [Annonce 8.5.0alpha1](https://github.com/derickr/toot-together/pull/42) + * [Annonce 8.5.0alpha2](https://github.com/derickr/toot-together/pull/47) + + We post to [@php@fosstodon.org](https://fosstodon.org/@php). ## Packaging a stable release @@ -564,7 +571,7 @@ slightly different steps. We'll call attention where the steps differ. # With ZTS make distclean || \ ./buildconf --force \ - && ./configure --enable-zts --disable-all --enable-debug --enable-opcache --enable-opcache-jit \ + && ./configure --enable-zts --disable-all --enable-debug --enable-opcache-jit \ && make -j$(nproc) \ && make test TEST_PHP_ARGS="-q -j$(nproc)" \ || ./sapi/cli/php -v @@ -572,7 +579,7 @@ slightly different steps. We'll call attention where the steps differ. # Without ZTS make distclean || \ ./buildconf --force \ - && ./configure --disable-all --enable-debug --enable-opcache --enable-opcache-jit \ + && ./configure --disable-all --enable-debug --enable-opcache-jit \ && make -j$(nproc) \ && make test TEST_PHP_ARGS="-q -j$(nproc)" \ || ./sapi/cli/php -v @@ -871,25 +878,37 @@ If you choose to create a patch-level release, follow these steps: mailinglist. -## Feature freeze +## Soft feature freeze -A major/minor version [feature freeze][] occurs with the first beta release. -Specifically, it occurs when the first beta release is packaged, which means the -feature freeze occurs two days before the first beta release. +A major/minor version soft feature freeze occurs with the first beta release. +This is a soft feature freeze because features can still be merged with RM +approval. -The feature freeze for `php-src` means that we will not accept any new features -after the date of the feature freeze. For any RFCs to be included in the new -version, they should be discussed and have the voting polls closed no later than -the feature freeze date. However, this does not mean the new feature must have a -complete implementation by this date. - -Following the feature freeze, the focus of work for the new version will be on -fixing bugs, writing tests, and completing/polishing all accepted features. +For any RFCs to be included in the new release, they should be discussed and +have their voting polls closed no later than when the first beta is released. +However, this does not mean the new feature must have a complete implementation +by this date. Such implementation can be merged only with RM approval and must +be done before the hard feature freeze. As a courtesy to the community, the release managers should remind others about -the upcoming feature freeze by posting reminders to internals@lists.php.net at -4-weeks, 3-weeks, 2-weeks, and 1-week prior to the feature freeze. This is a -recommendation and the intervals may vary based on work load. +the upcoming soft feature freeze by posting reminders to +internals@lists.php.net at 5 weeks, 4 weeks, 3 weeks, 2 weeks, and 1 week prior +to this feature freeze. This is a recommendation and the intervals may vary +based on workload. The reminder should also contain a note with dates for +the last allowed RFC to start voting. + +## Hard feature freeze + +A major/minor version hard [feature freeze][] occurs with the first RC release. +Specifically, it occurs when the first RC release is packaged, which means the +hard feature freeze occurs two days before the first RC release. + +The hard feature freeze for php-src means that we will not accept any new +features after the date of the hard feature freeze. + +Following the hard feature freeze, the focus of work for the new version will +be on fixing bugs, writing tests, and preparing documentation for all accepted +features. ## Forking a new version branch diff --git a/docs/source/miscellaneous/running-tests.rst b/docs/source/miscellaneous/running-tests.rst index c85e9f4c24d..bb2c56dcecd 100644 --- a/docs/source/miscellaneous/running-tests.rst +++ b/docs/source/miscellaneous/running-tests.rst @@ -11,16 +11,16 @@ work). Therefore you can execute the script as follows: .. code:: shell - TEST_PHP_EXECUTABLE=sapi/cli/php \ sapi/cli/php [-c /path/to/php.ini] run-tests.php [ext/foo/tests/GLOB] ****************************************** Which php executable does make test use? ****************************************** -If you are running the ``run-tests.php`` script from the command line (as above) you must set the +If you are running the ``run-tests.php`` script from the command line (as above) you can set the ``TEST_PHP_EXECUTABLE`` environment variable to explicitly select the PHP executable that is to be -tested, that is, used to run the test scripts. +tested, that is, used to run the test scripts, otherwise it will use the PHP CLI binary that you +have compiled (``sapi/cli/php``). If you run the tests using make test, the PHP CLI and CGI executables are automatically set for you. ``make test`` executes ``run-tests.php`` script with the CLI binary. Some test scripts such as @@ -58,6 +58,31 @@ Tester can easily execute tests selectively with as follows: ./sapi/cli/php run-tests.php ext/mbstring/* ./sapi/cli/php run-tests.php ext/mbstring/020.phpt +********************* + Test Runner Options +********************* + +The ``run-tests.php`` test runner has many options. You can see these options by using the ``-h`` +option with ``run-tests.php``. + +You can set options by specifying them on the command line when you run ``php run-tests.php`` or if +you use ``make test`` through the ``TEST_PHP_ARGS`` environment variable: + +.. code:: shell + + php run-tests.php -j24 + # or + TEST_PHP_ARGS="-j24" make test + +Running Tests in Parallel +========================= + +The test runner can run tests in parallel, by using the ``-j`` option: + +.. code:: shell + + php run-tests.php -j24 ext/date/*.phpt + ************** Test results ************** diff --git a/ext/calendar/calendar.c b/ext/calendar/calendar.c index 4cb6a2fa9a0..5e948fa1567 100644 --- a/ext/calendar/calendar.c +++ b/ext/calendar/calendar.c @@ -197,6 +197,16 @@ PHP_FUNCTION(cal_days_in_month) RETURN_THROWS(); } + if (UNEXPECTED(month <= 0 || month > INT32_MAX - 1)) { + zend_argument_value_error(2, "must be between 1 and %d", INT32_MAX - 1); + RETURN_THROWS(); + } + + if (UNEXPECTED(year > INT32_MAX - 1)) { + zend_argument_value_error(3, "must be less than %d", INT32_MAX - 1); + RETURN_THROWS(); + } + calendar = &cal_conversion_table[cal]; sdn_start = calendar->to_jd(year, month, 1); @@ -242,6 +252,21 @@ PHP_FUNCTION(cal_to_jd) RETURN_THROWS(); } + if (UNEXPECTED(month <= 0 || month > INT32_MAX - 1)) { + zend_argument_value_error(2, "must be between 1 and %d", INT32_MAX - 1); + RETURN_THROWS(); + } + + if (UNEXPECTED(ZEND_LONG_EXCEEDS_INT(day))) { + zend_argument_value_error(3, "must be between %d and %d", INT32_MIN, INT32_MAX); + RETURN_THROWS(); + } + + if (UNEXPECTED(year > INT32_MAX - 1)) { + zend_argument_value_error(4, "must be less than %d", INT32_MAX - 1); + RETURN_THROWS(); + } + RETURN_LONG(cal_conversion_table[cal].to_jd(year, month, day)); } /* }}} */ diff --git a/ext/calendar/tests/cal_days_in_month_error1.phpt b/ext/calendar/tests/cal_days_in_month_error1.phpt index f334888479f..e110c13cc2a 100644 --- a/ext/calendar/tests/cal_days_in_month_error1.phpt +++ b/ext/calendar/tests/cal_days_in_month_error1.phpt @@ -12,7 +12,7 @@ try { echo "{$ex->getMessage()}\n"; } try{ - cal_days_in_month(CAL_GREGORIAN,0, 2009); + cal_days_in_month(CAL_GREGORIAN,20, 2009); } catch (ValueError $ex) { echo "{$ex->getMessage()}\n"; } diff --git a/ext/calendar/tests/gh19371.phpt b/ext/calendar/tests/gh19371.phpt new file mode 100644 index 00000000000..1d807a98388 --- /dev/null +++ b/ext/calendar/tests/gh19371.phpt @@ -0,0 +1,61 @@ +--TEST-- +GH-19371 (integer overflow in calendar.c) +--SKIPIF-- + +--EXTENSIONS-- +calendar +--FILE-- +getMessage(), "\n"; +} +try { + echo cal_days_in_month(CAL_GREGORIAN, PHP_INT_MIN, 1); +} catch (ValueError $e) { + echo $e->getMessage(), "\n"; +} +try { + echo cal_days_in_month(CAL_GREGORIAN, PHP_INT_MAX, 1); +} catch (ValueError $e) { + echo $e->getMessage(), "\n"; +} + +try { + echo cal_to_jd(CAL_GREGORIAN, PHP_INT_MIN, 1, 1); +} catch (ValueError $e) { + echo $e->getMessage(), "\n"; +} +try { + echo cal_to_jd(CAL_GREGORIAN, PHP_INT_MAX, 1, 1); +} catch (ValueError $e) { + echo $e->getMessage(), "\n"; +} +try { + echo cal_to_jd(CAL_GREGORIAN, 1, PHP_INT_MIN, 1); +} catch (ValueError $e) { + echo $e->getMessage(), "\n"; +} +try { + echo cal_to_jd(CAL_GREGORIAN, 1, PHP_INT_MAX, 1); +} catch (ValueError $e) { + echo $e->getMessage(), "\n"; +} +try { + echo cal_to_jd(CAL_GREGORIAN, 1, 1, PHP_INT_MAX); +} catch (ValueError $e) { + echo $e->getMessage(), "\n"; +} + +?> +--EXPECT-- +cal_days_in_month(): Argument #3 ($year) must be less than 2147483646 +cal_days_in_month(): Argument #2 ($month) must be between 1 and 2147483646 +cal_days_in_month(): Argument #2 ($month) must be between 1 and 2147483646 +cal_to_jd(): Argument #2 ($month) must be between 1 and 2147483646 +cal_to_jd(): Argument #2 ($month) must be between 1 and 2147483646 +cal_to_jd(): Argument #3 ($day) must be between -2147483648 and 2147483647 +cal_to_jd(): Argument #3 ($day) must be between -2147483648 and 2147483647 +cal_to_jd(): Argument #4 ($year) must be less than 2147483646 diff --git a/ext/com_dotnet/com_handlers.c b/ext/com_dotnet/com_handlers.c index af980b7b86f..638fc5d8a3a 100644 --- a/ext/com_dotnet/com_handlers.c +++ b/ext/com_dotnet/com_handlers.c @@ -514,6 +514,7 @@ zend_object_handlers php_com_object_handlers = { php_com_object_free_storage, zend_objects_destroy_object, php_com_object_clone, + NULL, /* clone_with */ com_property_read, com_property_write, com_read_dimension, diff --git a/ext/com_dotnet/com_saproxy.c b/ext/com_dotnet/com_saproxy.c index ea0e9e47a13..ec79faa30a3 100644 --- a/ext/com_dotnet/com_saproxy.c +++ b/ext/com_dotnet/com_saproxy.c @@ -402,6 +402,7 @@ zend_object_handlers php_com_saproxy_handlers = { saproxy_free_storage, zend_objects_destroy_object, saproxy_clone, + NULL, /* clone_with */ saproxy_property_read, saproxy_property_write, saproxy_read_dimension, diff --git a/ext/com_dotnet/com_variant.c b/ext/com_dotnet/com_variant.c index 23cbd078fb4..7e63d66b3d3 100644 --- a/ext/com_dotnet/com_variant.c +++ b/ext/com_dotnet/com_variant.c @@ -32,7 +32,7 @@ static void safe_array_from_zval(VARIANT *v, zval *z, int codepage) SAFEARRAY *sa = NULL; SAFEARRAYBOUND bound; HashPosition pos; - int keytype; + zend_hash_key_type keytype; zend_string *strindex; zend_ulong intindex = 0; VARIANT *va; diff --git a/ext/com_dotnet/com_wrapper.c b/ext/com_dotnet/com_wrapper.c index 6e885fa802e..3d05e17affa 100644 --- a/ext/com_dotnet/com_wrapper.c +++ b/ext/com_dotnet/com_wrapper.c @@ -423,7 +423,7 @@ static void generate_dispids(php_dispatchex *disp) HashPosition pos; zend_string *name = NULL; zval *tmp, tmp2; - int keytype; + zend_hash_key_type keytype; zend_long pid; if (disp->dispid_to_name == NULL) { diff --git a/ext/ctype/tests/lc_ctype_inheritance.phpt b/ext/ctype/tests/lc_ctype_inheritance.phpt index 6f37941d8f4..98a0c35cf00 100644 --- a/ext/ctype/tests/lc_ctype_inheritance.phpt +++ b/ext/ctype/tests/lc_ctype_inheritance.phpt @@ -4,6 +4,7 @@ Do not inherit LC_CTYPE from environment ctype --SKIPIF-- diff --git a/ext/curl/config.m4 b/ext/curl/config.m4 index f3c39b4c517..bbb41fdde32 100644 --- a/ext/curl/config.m4 +++ b/ext/curl/config.m4 @@ -15,8 +15,8 @@ if test "$PHP_CURL" != "no"; then AC_MSG_RESULT([$CURL_SSL]) AS_IF([test "x$PHP_THREAD_SAFETY" = xyes && test "x$CURL_SSL" = xyes], - [AC_CACHE_CHECK([whether libcurl is linked against old OpenSSL < 1.1], - [php_cv_lib_curl_ssl], [ + [AC_CACHE_CHECK([whether libcurl is linked against a supported OpenSSL version], + [php_cv_lib_curl_ssl_supported], [ save_LIBS=$LIBS save_CFLAGS=$CFLAGS LIBS="$LIBS $CURL_SHARED_LIBADD" @@ -34,17 +34,14 @@ if test "$PHP_CURL" != "no"; then while(*ptr == ' ') ++ptr; int major, minor; - if (sscanf(ptr, "OpenSSL/%d", &major) == 1) { - if (major >= 3) { - /* OpenSSL version 3 or later */ - return 4; - } - } if (sscanf(ptr, "OpenSSL/%d.%d", &major, &minor) == 2) { - if (major > 1 || (major == 1 && minor >= 1)) { - /* OpenSSL version 1.1 or later */ + /* Check for 1.1.1+ (including 1.1.1a, 1.1.1b, etc.) */ + if ((major > 1) || (major == 1 && minor == 1 && strncmp(ptr + 12, "1", 1) == 0)) { + /* OpenSSL 1.1.1+ - supported */ return 3; } + /* OpenSSL 1.1.0 and earlier - unsupported */ + return 0; } if (strncasecmp(ptr, "OpenSSL", sizeof("OpenSSL")-1) == 0) { /* Old OpenSSL version */ @@ -56,18 +53,15 @@ if test "$PHP_CURL" != "no"; then /* No SSL support */ return 1; ])], - [php_cv_lib_curl_ssl=yes], - [php_cv_lib_curl_ssl=no], - [php_cv_lib_curl_ssl=no]) + [php_cv_lib_curl_ssl_supported=no], + [php_cv_lib_curl_ssl_supported=yes], + [php_cv_lib_curl_ssl_supported=yes]) LIBS=$save_LIBS CFLAGS=$save_CFLAGS ]) - AS_VAR_IF([php_cv_lib_curl_ssl], [yes], [ - AC_DEFINE([HAVE_CURL_OLD_OPENSSL], [1], - [Define to 1 if libcurl is linked against old OpenSSL < 1.1.]) - PHP_SETUP_OPENSSL([CURL_SHARED_LIBADD], - [AC_CHECK_HEADERS([openssl/crypto.h])]) + AS_VAR_IF([php_cv_lib_curl_ssl_supported], [no], [ + AC_MSG_ERROR([libcurl is linked against an unsupported OpenSSL version. OpenSSL 1.1.1 or later is required.]) ]) ]) diff --git a/ext/curl/curl.stub.php b/ext/curl/curl.stub.php index 00532f45793..c9cda9c0d4b 100644 --- a/ext/curl/curl.stub.php +++ b/ext/curl/curl.stub.php @@ -3054,6 +3054,13 @@ const CURL_LOCK_DATA_PSL = UNKNOWN; * @cvalue CURLAUTH_BEARER */ const CURLAUTH_BEARER = UNKNOWN; +#if LIBCURL_VERSION_NUM >= 0x080600 /* Available since 8.6.0 */ +/** + * @var int + * @cvalue CURLINFO_QUEUE_TIME_T + */ +const CURLINFO_QUEUE_TIME_T = UNKNOWN; +#endif /** * @var int * @cvalue CURLINFO_APPCONNECT_TIME_T @@ -3103,6 +3110,13 @@ const CURLINFO_USED_PROXY = UNKNOWN; */ const CURLINFO_POSTTRANSFER_TIME_T = UNKNOWN; #endif +#if LIBCURL_VERSION_NUM >= 0x080200 /* Available since 8.2.0 */ +/** + * @var int + * @cvalue CURLINFO_CONN_ID + */ +const CURLINFO_CONN_ID = UNKNOWN; +#endif /** * @var int * @cvalue CURLOPT_DISALLOW_USERNAME_IN_URL @@ -3325,6 +3339,13 @@ const CURLINFO_PROXY_ERROR = UNKNOWN; * @cvalue CURLOPT_SSL_EC_CURVES */ const CURLOPT_SSL_EC_CURVES = UNKNOWN; +#if LIBCURL_VERSION_NUM >= 0x080e00 /* Available since 8.14.0 */ +/** + * @var int + * @cvalue CURLOPT_SSL_SIGNATURE_ALGORITHMS + */ +const CURLOPT_SSL_SIGNATURE_ALGORITHMS = UNKNOWN; +#endif /** * @var int * @cvalue CURLPX_BAD_ADDRESS_TYPE @@ -3719,6 +3740,7 @@ final class CurlSharePersistentHandle public readonly array $options; } +#[\Deprecated(since: '8.5', message: "as it has no effect since PHP 8.0")] function curl_close(CurlHandle $handle): void {} /** @refcount 1 */ @@ -3789,6 +3811,7 @@ function curl_setopt_array(CurlHandle $handle, array $options): bool {} function curl_setopt(CurlHandle $handle, int $option, mixed $value): bool {} +#[\Deprecated(since: '8.5', message: "as it has no effect since PHP 8.0")] function curl_share_close(CurlShareHandle $share_handle): void {} function curl_share_errno(CurlShareHandle $share_handle): int {} diff --git a/ext/curl/curl_arginfo.h b/ext/curl/curl_arginfo.h index 1defefdab2d..b511ff077de 100644 --- a/ext/curl/curl_arginfo.h +++ b/ext/curl/curl_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: c087ac501d0abe14ed87968023d837f358e6fee8 */ + * Stub hash: 2a2772e99deea07c0bc148e9715e6a960230cf4d */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_curl_close, 0, 1, IS_VOID, 0) ZEND_ARG_OBJ_INFO(0, handle, CurlHandle, 0) @@ -185,7 +185,7 @@ ZEND_FUNCTION(curl_strerror); ZEND_FUNCTION(curl_version); static const zend_function_entry ext_functions[] = { - ZEND_FE(curl_close, arginfo_curl_close) + ZEND_RAW_FENTRY("curl_close", zif_curl_close, arginfo_curl_close, ZEND_ACC_DEPRECATED, NULL, NULL) ZEND_FE(curl_copy_handle, arginfo_curl_copy_handle) ZEND_FE(curl_errno, arginfo_curl_errno) ZEND_FE(curl_error, arginfo_curl_error) @@ -214,7 +214,7 @@ static const zend_function_entry ext_functions[] = { ZEND_FE(curl_reset, arginfo_curl_reset) ZEND_FE(curl_setopt_array, arginfo_curl_setopt_array) ZEND_FE(curl_setopt, arginfo_curl_setopt) - ZEND_FE(curl_share_close, arginfo_curl_share_close) + ZEND_RAW_FENTRY("curl_share_close", zif_curl_share_close, arginfo_curl_share_close, ZEND_ACC_DEPRECATED, NULL, NULL) ZEND_FE(curl_share_errno, arginfo_curl_share_errno) ZEND_FE(curl_share_init, arginfo_curl_share_init) ZEND_FE(curl_share_setopt, arginfo_curl_share_setopt) @@ -812,6 +812,9 @@ static void register_curl_symbols(int module_number) REGISTER_LONG_CONSTANT("CURLOPT_HAPROXYPROTOCOL", CURLOPT_HAPROXYPROTOCOL, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("CURL_LOCK_DATA_PSL", CURL_LOCK_DATA_PSL, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("CURLAUTH_BEARER", CURLAUTH_BEARER, CONST_PERSISTENT); +#if LIBCURL_VERSION_NUM >= 0x080600 /* Available since 8.6.0 */ + REGISTER_LONG_CONSTANT("CURLINFO_QUEUE_TIME_T", CURLINFO_QUEUE_TIME_T, CONST_PERSISTENT); +#endif REGISTER_LONG_CONSTANT("CURLINFO_APPCONNECT_TIME_T", CURLINFO_APPCONNECT_TIME_T, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("CURLINFO_CONNECT_TIME_T", CURLINFO_CONNECT_TIME_T, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("CURLINFO_NAMELOOKUP_TIME_T", CURLINFO_NAMELOOKUP_TIME_T, CONST_PERSISTENT); @@ -824,6 +827,9 @@ static void register_curl_symbols(int module_number) #endif #if LIBCURL_VERSION_NUM >= 0x080a00 /* Available since 8.10.0 */ REGISTER_LONG_CONSTANT("CURLINFO_POSTTRANSFER_TIME_T", CURLINFO_POSTTRANSFER_TIME_T, CONST_PERSISTENT); +#endif +#if LIBCURL_VERSION_NUM >= 0x080200 /* Available since 8.2.0 */ + REGISTER_LONG_CONSTANT("CURLINFO_CONN_ID", CURLINFO_CONN_ID, CONST_PERSISTENT); #endif REGISTER_LONG_CONSTANT("CURLOPT_DISALLOW_USERNAME_IN_URL", CURLOPT_DISALLOW_USERNAME_IN_URL, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("CURLOPT_PROXY_TLS13_CIPHERS", CURLOPT_PROXY_TLS13_CIPHERS, CONST_PERSISTENT); @@ -885,6 +891,11 @@ static void register_curl_symbols(int module_number) REGISTER_LONG_CONSTANT("CURLE_PROXY", CURLE_PROXY, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("CURLINFO_PROXY_ERROR", CURLINFO_PROXY_ERROR, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("CURLOPT_SSL_EC_CURVES", CURLOPT_SSL_EC_CURVES, CONST_PERSISTENT); +#endif +#if LIBCURL_VERSION_NUM >= 0x074900 /* Available since 7.73.0 */ && LIBCURL_VERSION_NUM >= 0x080e00 /* Available since 8.14.0 */ + REGISTER_LONG_CONSTANT("CURLOPT_SSL_SIGNATURE_ALGORITHMS", CURLOPT_SSL_SIGNATURE_ALGORITHMS, CONST_PERSISTENT); +#endif +#if LIBCURL_VERSION_NUM >= 0x074900 /* Available since 7.73.0 */ REGISTER_LONG_CONSTANT("CURLPX_BAD_ADDRESS_TYPE", CURLPX_BAD_ADDRESS_TYPE, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("CURLPX_BAD_VERSION", CURLPX_BAD_VERSION, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("CURLPX_CLOSED", CURLPX_CLOSED, CONST_PERSISTENT); @@ -975,13 +986,24 @@ static void register_curl_symbols(int module_number) REGISTER_LONG_CONSTANT("CURLOPT_SAFE_UPLOAD", CURLOPT_SAFE_UPLOAD, CONST_PERSISTENT); + zend_attribute *attribute_Deprecated_func_curl_close_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "curl_close", sizeof("curl_close") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + ZVAL_STR(&attribute_Deprecated_func_curl_close_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_5)); + attribute_Deprecated_func_curl_close_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zend_string *attribute_Deprecated_func_curl_close_0_arg1_str = zend_string_init("as it has no effect since PHP 8.0", strlen("as it has no effect since PHP 8.0"), 1); + ZVAL_STR(&attribute_Deprecated_func_curl_close_0->args[1].value, attribute_Deprecated_func_curl_close_0_arg1_str); + attribute_Deprecated_func_curl_close_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + + zend_attribute *attribute_Deprecated_func_curl_share_close_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "curl_share_close", sizeof("curl_share_close") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + ZVAL_STR(&attribute_Deprecated_func_curl_share_close_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_5)); + attribute_Deprecated_func_curl_share_close_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + ZVAL_STR_COPY(&attribute_Deprecated_func_curl_share_close_0->args[1].value, attribute_Deprecated_func_curl_close_0_arg1_str); + attribute_Deprecated_func_curl_share_close_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + zend_attribute *attribute_Deprecated_const_CURLOPT_BINARYTRANSFER_0 = zend_add_global_constant_attribute(const_CURLOPT_BINARYTRANSFER, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_const_CURLOPT_BINARYTRANSFER_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_4)); attribute_Deprecated_const_CURLOPT_BINARYTRANSFER_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_const_CURLOPT_BINARYTRANSFER_0_arg1; zend_string *attribute_Deprecated_const_CURLOPT_BINARYTRANSFER_0_arg1_str = zend_string_init("as it had no effect since 5.1.2", strlen("as it had no effect since 5.1.2"), 1); - ZVAL_STR(&attribute_Deprecated_const_CURLOPT_BINARYTRANSFER_0_arg1, attribute_Deprecated_const_CURLOPT_BINARYTRANSFER_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_const_CURLOPT_BINARYTRANSFER_0->args[1].value, &attribute_Deprecated_const_CURLOPT_BINARYTRANSFER_0_arg1); + ZVAL_STR(&attribute_Deprecated_const_CURLOPT_BINARYTRANSFER_0->args[1].value, attribute_Deprecated_const_CURLOPT_BINARYTRANSFER_0_arg1_str); attribute_Deprecated_const_CURLOPT_BINARYTRANSFER_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); } diff --git a/ext/curl/interface.c b/ext/curl/interface.c index 4cba1e4d328..53098c64eb0 100644 --- a/ext/curl/interface.c +++ b/ext/curl/interface.c @@ -39,20 +39,6 @@ #define HttpPost curl_httppost #endif -/* {{{ cruft for thread safe SSL crypto locks */ -#if defined(ZTS) && defined(HAVE_CURL_OLD_OPENSSL) -# if defined(HAVE_OPENSSL_CRYPTO_H) -# define PHP_CURL_NEED_OPENSSL_TSL -# include -# else -# warning \ - "libcurl was compiled with OpenSSL support, but configure could not find " \ - "openssl/crypto.h; thus no SSL crypto locking callbacks will be set, which may " \ - "cause random crashes on SSL requests" -# endif -#endif /* ZTS && HAVE_CURL_OLD_OPENSSL */ -/* }}} */ - #include "zend_smart_str.h" #include "ext/standard/info.h" #include "ext/standard/file.h" @@ -70,27 +56,6 @@ ZEND_DECLARE_MODULE_GLOBALS(curl) -#ifdef PHP_CURL_NEED_OPENSSL_TSL /* {{{ */ -static MUTEX_T *php_curl_openssl_tsl = NULL; - -/* Locking callbacks are no longer used since OpenSSL 1.1. Mark the functions as unused to - * avoid warnings due to this. */ -static ZEND_ATTRIBUTE_UNUSED void php_curl_ssl_lock(int mode, int n, const char * file, int line) -{ - if (mode & CRYPTO_LOCK) { - tsrm_mutex_lock(php_curl_openssl_tsl[n]); - } else { - tsrm_mutex_unlock(php_curl_openssl_tsl[n]); - } -} - -static ZEND_ATTRIBUTE_UNUSED unsigned long php_curl_ssl_id(void) -{ - return (unsigned long) tsrm_thread_id(); -} -#endif -/* }}} */ - #define CAAL(s, v) add_assoc_long_ex(return_value, s, sizeof(s) - 1, (zend_long) v); #define CAAD(s, v) add_assoc_double_ex(return_value, s, sizeof(s) - 1, (double) v); #define CAAS(s, v) add_assoc_string_ex(return_value, s, sizeof(s) - 1, (char *) (v ? v : "")); @@ -389,24 +354,6 @@ PHP_MINIT_FUNCTION(curl) register_curl_symbols(module_number); -#ifdef PHP_CURL_NEED_OPENSSL_TSL - if (!CRYPTO_get_id_callback()) { - int i, c = CRYPTO_num_locks(); - - php_curl_openssl_tsl = malloc(c * sizeof(MUTEX_T)); - if (!php_curl_openssl_tsl) { - return FAILURE; - } - - for (i = 0; i < c; ++i) { - php_curl_openssl_tsl[i] = tsrm_mutex_alloc(); - } - - CRYPTO_set_id_callback(php_curl_ssl_id); - CRYPTO_set_locking_callback(php_curl_ssl_lock); - } -#endif - if (curl_global_init(CURL_GLOBAL_DEFAULT) != CURLE_OK) { return FAILURE; } @@ -568,21 +515,6 @@ zend_result curl_cast_object(zend_object *obj, zval *result, int type) PHP_MSHUTDOWN_FUNCTION(curl) { curl_global_cleanup(); -#ifdef PHP_CURL_NEED_OPENSSL_TSL - if (php_curl_openssl_tsl) { - int i, c = CRYPTO_num_locks(); - - CRYPTO_set_id_callback(NULL); - CRYPTO_set_locking_callback(NULL); - - for (i = 0; i < c; ++i) { - tsrm_mutex_free(php_curl_openssl_tsl[i]); - } - - free(php_curl_openssl_tsl); - php_curl_openssl_tsl = NULL; - } -#endif UNREGISTER_INI_ENTRIES(); return SUCCESS; } @@ -2012,6 +1944,9 @@ static zend_result _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue case CURLOPT_USERPWD: case CURLOPT_USERNAME: case CURLOPT_PASSWORD: +#if LIBCURL_VERSION_NUM >= 0x080e00 /* Available since 8.14.0 */ + case CURLOPT_SSL_SIGNATURE_ALGORITHMS: +#endif { if (Z_ISNULL_P(zvalue)) { error = curl_easy_setopt(ch->cp, option, NULL); @@ -2639,6 +2574,11 @@ PHP_FUNCTION(curl_getinfo) if (curl_easy_getinfo(ch->cp, CURLINFO_APPCONNECT_TIME_T, &co) == CURLE_OK) { CAAL("appconnect_time_us", co); } +#if LIBCURL_VERSION_NUM >= 0x080600 /* Available since 8.6.0 */ + if (curl_easy_getinfo(ch->cp, CURLINFO_QUEUE_TIME_T , &co) == CURLE_OK) { + CAAL("queue_time_us", co); + } +#endif if (curl_easy_getinfo(ch->cp, CURLINFO_CONNECT_TIME_T, &co) == CURLE_OK) { CAAL("connect_time_us", co); } @@ -2690,6 +2630,11 @@ PHP_FUNCTION(curl_getinfo) if (curl_easy_getinfo(ch->cp, CURLINFO_PROXYAUTH_USED, &l_code) == CURLE_OK) { CAAL("proxyauth_used", l_code); } +#endif +#if LIBCURL_VERSION_NUM >= 0x080200 /* Available since 8.2.0 */ + if (curl_easy_getinfo(ch->cp, CURLINFO_CONN_ID , &co) == CURLE_OK) { + CAAL("conn_id", co); + } #endif } else { switch (option) { diff --git a/ext/curl/tests/Caddyfile b/ext/curl/tests/Caddyfile index ceba97ee939..f6f4279af89 100644 --- a/ext/curl/tests/Caddyfile +++ b/ext/curl/tests/Caddyfile @@ -21,3 +21,8 @@ basic_auth /http-basic-auth { # bcrypt password hash for "password", calculated with 'caddy hash-password' user $2a$14$yUKl9SGqVTAAqPTzLup.DefsbXXx3kfreNnzpJOUHcIrKnr5lgef2 } + +route /ping { + templates + respond `pong` +} diff --git a/ext/curl/tests/bug27023.phpt b/ext/curl/tests/bug27023.phpt index 7d6850d75cc..7b8ddf6d92b 100644 --- a/ext/curl/tests/bug27023.phpt +++ b/ext/curl/tests/bug27023.phpt @@ -33,9 +33,6 @@ $file = curl_file_create(__DIR__ . '/curl_testdata1.txt', "text/plain", "foo.txt $params = array('file' => $file); curl_setopt($ch, CURLOPT_POSTFIELDS, $params); var_dump(curl_exec($ch)); - - -curl_close($ch); ?> --EXPECTF-- string(%d) "curl_testdata1.txt|application/octet-stream|6" diff --git a/ext/curl/tests/bug48203.phpt b/ext/curl/tests/bug48203.phpt index 1f1423cbee9..23d61964b5e 100644 --- a/ext/curl/tests/bug48203.phpt +++ b/ext/curl/tests/bug48203.phpt @@ -16,7 +16,6 @@ curl_setopt($ch, CURLOPT_URL, curl_cli_server_start()); fclose($fp); // <-- premature close of $fp caused a crash! curl_exec($ch); -curl_close($ch); echo "Ok\n"; diff --git a/ext/curl/tests/bug48207.phpt b/ext/curl/tests/bug48207.phpt index 982744c7852..086f949ff63 100644 --- a/ext/curl/tests/bug48207.phpt +++ b/ext/curl/tests/bug48207.phpt @@ -43,7 +43,6 @@ try { } curl_exec($ch); -curl_close($ch); is_file($tempfile) and @unlink($tempfile); isset($tempname) and is_file($tempname) and @unlink($tempname); ?> diff --git a/ext/curl/tests/bug54798-unix.phpt b/ext/curl/tests/bug54798-unix.phpt index 6eb5099b31b..6bbca3375ed 100644 --- a/ext/curl/tests/bug54798-unix.phpt +++ b/ext/curl/tests/bug54798-unix.phpt @@ -34,8 +34,6 @@ function checkForClosedFilePointer($host, $curl_option, $description) { curl_exec($ch); - curl_close($ch); - echo "Ok for $description\n"; } diff --git a/ext/curl/tests/bug54798.phpt b/ext/curl/tests/bug54798.phpt index 4403b5212aa..da38b72d775 100644 --- a/ext/curl/tests/bug54798.phpt +++ b/ext/curl/tests/bug54798.phpt @@ -28,8 +28,6 @@ function checkForClosedFilePointer($host, $curl_option, $description) { curl_exec($ch); - curl_close($ch); - echo "Ok for $description\n"; } diff --git a/ext/curl/tests/bug55767.phpt b/ext/curl/tests/bug55767.phpt index a57da6e6d88..50572f295f7 100644 --- a/ext/curl/tests/bug55767.phpt +++ b/ext/curl/tests/bug55767.phpt @@ -20,7 +20,6 @@ curl curl_setopt($ch, CURLOPT_URL, $url); //set the url we want to use $curl_content = curl_exec($ch); - curl_close($ch); var_dump( $curl_content ); ?> diff --git a/ext/curl/tests/bug61948-unix.phpt b/ext/curl/tests/bug61948-unix.phpt index 0b5d9b85989..09c7c3ecb9e 100644 --- a/ext/curl/tests/bug61948-unix.phpt +++ b/ext/curl/tests/bug61948-unix.phpt @@ -14,7 +14,6 @@ open_basedir="/tmp" var_dump(curl_setopt($ch, CURLOPT_COOKIEFILE, "")); var_dump(curl_setopt($ch, CURLOPT_COOKIEFILE, "/tmp/foo")); var_dump(curl_setopt($ch, CURLOPT_COOKIEFILE, "/xxx/bar")); - curl_close($ch); ?> --EXPECTF-- bool(true) diff --git a/ext/curl/tests/bug61948.phpt b/ext/curl/tests/bug61948.phpt index 1245c3a6999..80941344f0c 100644 --- a/ext/curl/tests/bug61948.phpt +++ b/ext/curl/tests/bug61948.phpt @@ -13,7 +13,6 @@ curl var_dump(curl_setopt($ch, CURLOPT_COOKIEFILE, "")); var_dump(curl_setopt($ch, CURLOPT_COOKIEFILE, "$base_dir/foo")); var_dump(curl_setopt($ch, CURLOPT_COOKIEFILE, "c:/xxx/bar")); - curl_close($ch); ?> --CLEAN-- --EXPECTF-- bool(true) diff --git a/ext/curl/tests/bug65458.phpt b/ext/curl/tests/bug65458.phpt index f19e7a289a4..83b46057a37 100644 --- a/ext/curl/tests/bug65458.phpt +++ b/ext/curl/tests/bug65458.phpt @@ -11,7 +11,7 @@ for ($i = 0; $i < 10000; $i++) { } $preclose = memory_get_usage(); -curl_close($ch); +$ch = null; // This is a slightly tricky heuristic, but basically, we want to ensure // $preclose - $init has a delta in the order of bytes, not megabytes. Given diff --git a/ext/curl/tests/bug65646.phpt b/ext/curl/tests/bug65646.phpt index 1c9f602367c..2f83b7f5afa 100644 --- a/ext/curl/tests/bug65646.phpt +++ b/ext/curl/tests/bug65646.phpt @@ -10,7 +10,6 @@ if (ini_get('open_basedir')) exit("skip open_basedir is set"); --EXPECT-- bool(true) diff --git a/ext/curl/tests/bug65646_open_basedir_new.phpt b/ext/curl/tests/bug65646_open_basedir_new.phpt index 5ea40252f9a..80d6c7ffbf7 100644 --- a/ext/curl/tests/bug65646_open_basedir_new.phpt +++ b/ext/curl/tests/bug65646_open_basedir_new.phpt @@ -10,7 +10,6 @@ $ch = curl_init(); var_dump(curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true)); var_dump(curl_setopt($ch, CURLOPT_PROTOCOLS, CURLPROTO_FILE)); var_dump(curl_setopt($ch, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_FILE)); -curl_close($ch); ?> --EXPECTF-- bool(true) diff --git a/ext/curl/tests/bug66109.phpt b/ext/curl/tests/bug66109.phpt index 48fcfb4beed..623ad20f863 100644 --- a/ext/curl/tests/bug66109.phpt +++ b/ext/curl/tests/bug66109.phpt @@ -15,9 +15,6 @@ var_dump(curl_exec($ch)); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, NULL); var_dump(curl_exec($ch)); - -curl_close($ch); - ?> --EXPECT-- string(6) "DELETE" diff --git a/ext/curl/tests/bug68937.phpt b/ext/curl/tests/bug68937.phpt index 7c42483f9fa..884947b8c45 100644 --- a/ext/curl/tests/bug68937.phpt +++ b/ext/curl/tests/bug68937.phpt @@ -31,7 +31,6 @@ function curl_read($ch, $fp, $len) { } curl_exec($ch); -curl_close($ch); ?> --EXPECT-- NULL diff --git a/ext/curl/tests/bug68937_2.phpt b/ext/curl/tests/bug68937_2.phpt index 596bbfa4b37..7ae67acf00a 100644 --- a/ext/curl/tests/bug68937_2.phpt +++ b/ext/curl/tests/bug68937_2.phpt @@ -31,7 +31,6 @@ function curl_read($ch, $fp, $len) { } curl_exec($ch); -curl_close($ch); ?> --EXPECTF-- resource(%d) of type (stream) diff --git a/ext/curl/tests/bug69316.phpt b/ext/curl/tests/bug69316.phpt index 3e0e049d08e..2cbcb560d5a 100644 --- a/ext/curl/tests/bug69316.phpt +++ b/ext/curl/tests/bug69316.phpt @@ -27,7 +27,6 @@ curl curl_setopt($ch, CURLOPT_FILE, $f_file); curl_setopt($ch, CURLOPT_URL, $url); curl_exec($ch); - curl_close($ch); ?> --CLEAN-- $file); var_dump(curl_setopt($ch, CURLOPT_POSTFIELDS, $params)); var_dump(curl_exec($ch)); -curl_close($ch); ?> --EXPECTF-- bool(true) diff --git a/ext/curl/tests/bug77946.phpt b/ext/curl/tests/bug77946.phpt index 7b836187d6b..fa871d21cc7 100644 --- a/ext/curl/tests/bug77946.phpt +++ b/ext/curl/tests/bug77946.phpt @@ -25,10 +25,6 @@ do { } } while ($status === CURLM_CALL_MULTI_PERFORM || $active); -foreach ($urls as $i => $url) { - curl_close($conn[$i]); -} - curl_multi_close($mh); ?> --EXPECTF-- diff --git a/ext/curl/tests/bug78775.phpt b/ext/curl/tests/bug78775.phpt index 3e2ece28445..db68c26e6ba 100644 --- a/ext/curl/tests/bug78775.phpt +++ b/ext/curl/tests/bug78775.phpt @@ -24,7 +24,6 @@ curl_setopt_array( ); var_dump(curl_exec($handle)); -curl_close($handle); fwrite($sock, "GET / HTTP/1.0\n\n"); var_dump(fread($sock, 8)); diff --git a/ext/curl/tests/bug79199.phpt b/ext/curl/tests/bug79199.phpt index c67bfffd5e1..9cabe8ac393 100644 --- a/ext/curl/tests/bug79199.phpt +++ b/ext/curl/tests/bug79199.phpt @@ -8,8 +8,8 @@ $mem_old = 0; for($i = 0; $i < 50; ++$i) { $c1 = curl_init(); $c2 = curl_copy_handle($c1); - curl_close($c2); - curl_close($c1); + $c2 = null; + $c1 = null; $mem_new = memory_get_usage(); if ($mem_new <= $mem_old) { break; diff --git a/ext/curl/tests/curl_CURLOPT_READDATA.phpt b/ext/curl/tests/curl_CURLOPT_READDATA.phpt index 21d394a674c..14f2b606fa0 100644 --- a/ext/curl/tests/curl_CURLOPT_READDATA.phpt +++ b/ext/curl/tests/curl_CURLOPT_READDATA.phpt @@ -32,8 +32,6 @@ if (false === $response = curl_exec($ch)) { echo $response; } -curl_close($ch); - // Clean the temporary file @unlink($tempname); ?> diff --git a/ext/curl/tests/curl_basic_001.phpt b/ext/curl/tests/curl_basic_001.phpt index f89394acdac..45ef816b563 100644 --- a/ext/curl/tests/curl_basic_001.phpt +++ b/ext/curl/tests/curl_basic_001.phpt @@ -19,7 +19,6 @@ curl ob_start(); // start output buffering curl_setopt($ch, CURLOPT_URL, $url); //set the url we want to use $ok = curl_exec($ch); - curl_close($ch); $curl_content = ob_get_contents(); ob_end_clean(); diff --git a/ext/curl/tests/curl_basic_002.phpt b/ext/curl/tests/curl_basic_002.phpt index 1b79fc0d6dc..5a4dbbef9a5 100644 --- a/ext/curl/tests/curl_basic_002.phpt +++ b/ext/curl/tests/curl_basic_002.phpt @@ -21,8 +21,6 @@ curl curl_setopt($ch, CURLOPT_URL, $url); //set the url we want to use $curl_content = curl_exec($ch); - curl_close($ch); - var_dump( $curl_content ); ?> --EXPECT-- diff --git a/ext/curl/tests/curl_basic_003.phpt b/ext/curl/tests/curl_basic_003.phpt index cc578b9b505..1f3fd07f428 100644 --- a/ext/curl/tests/curl_basic_003.phpt +++ b/ext/curl/tests/curl_basic_003.phpt @@ -23,8 +23,6 @@ curl curl_setopt($ch, CURLOPT_URL, $url); //set the url we want to use $curl_content = curl_exec($ch); - curl_close($ch); - var_dump( $curl_content ); ?> --EXPECT-- diff --git a/ext/curl/tests/curl_basic_004.phpt b/ext/curl/tests/curl_basic_004.phpt index eb89987a313..446d0feb983 100644 --- a/ext/curl/tests/curl_basic_004.phpt +++ b/ext/curl/tests/curl_basic_004.phpt @@ -22,8 +22,6 @@ curl curl_setopt($ch, CURLOPT_URL, $url); //set the url we want to use $curl_content = curl_exec($ch); - curl_close($ch); - var_dump( $curl_content ); ?> --EXPECT-- diff --git a/ext/curl/tests/curl_basic_005.phpt b/ext/curl/tests/curl_basic_005.phpt index 542e253d53e..9bcbb5c11bf 100644 --- a/ext/curl/tests/curl_basic_005.phpt +++ b/ext/curl/tests/curl_basic_005.phpt @@ -22,8 +22,6 @@ curl curl_setopt($ch, CURLOPT_URL, $url); //set the url we want to use $curl_content = curl_exec($ch); - curl_close($ch); - var_dump( $curl_content ); ?> --EXPECT-- diff --git a/ext/curl/tests/curl_basic_006.phpt b/ext/curl/tests/curl_basic_006.phpt index a39eaa06b7c..f0142d8333f 100644 --- a/ext/curl/tests/curl_basic_006.phpt +++ b/ext/curl/tests/curl_basic_006.phpt @@ -24,7 +24,6 @@ curl }); curl_exec($ch); - curl_close($ch); ob_end_flush(); echo "Data: $alldata"; ?> diff --git a/ext/curl/tests/curl_basic_007.phpt b/ext/curl/tests/curl_basic_007.phpt index 3834e4674f8..1ae0ec72186 100644 --- a/ext/curl/tests/curl_basic_007.phpt +++ b/ext/curl/tests/curl_basic_007.phpt @@ -15,9 +15,6 @@ $ch = curl_init(); curl_exec($ch); var_dump(curl_error($ch)); var_dump(curl_errno($ch)); -curl_close($ch); - - ?> --EXPECTF-- string(%d) "No URL set%A" diff --git a/ext/curl/tests/curl_basic_008.phpt b/ext/curl/tests/curl_basic_008.phpt index 353c44327c5..d9601dfcac1 100644 --- a/ext/curl/tests/curl_basic_008.phpt +++ b/ext/curl/tests/curl_basic_008.phpt @@ -21,9 +21,6 @@ curl_setopt($ch, CURLOPT_URL, $url); curl_exec($ch); var_dump(curl_error($ch)); var_dump(curl_errno($ch)); -curl_close($ch); - - ?> --EXPECTF-- %s resolve%s diff --git a/ext/curl/tests/curl_basic_009.phpt b/ext/curl/tests/curl_basic_009.phpt index ade7cffcb82..b6c2b2fd418 100644 --- a/ext/curl/tests/curl_basic_009.phpt +++ b/ext/curl/tests/curl_basic_009.phpt @@ -15,9 +15,6 @@ curl_setopt($ch, CURLOPT_URL, $url); curl_exec($ch); var_dump(curl_error($ch)); var_dump(curl_errno($ch)); -curl_close($ch); - - ?> --EXPECTF-- string(%d) "%Srotocol%s" diff --git a/ext/curl/tests/curl_basic_010.phpt b/ext/curl/tests/curl_basic_010.phpt index 7920408dc55..908886b2e84 100644 --- a/ext/curl/tests/curl_basic_010.phpt +++ b/ext/curl/tests/curl_basic_010.phpt @@ -22,9 +22,6 @@ curl_setopt($ch, CURLOPT_URL, $url); curl_exec($ch); var_dump(curl_error($ch)); var_dump(curl_errno($ch)); -curl_close($ch); - - ?> --EXPECTF-- string(%d) "%r(Couldn't resolve proxy|Could not resolve proxy:|Could not resolve host:|Could not resolve:|Unsupported proxy syntax in)%r %s" diff --git a/ext/curl/tests/curl_basic_011.phpt b/ext/curl/tests/curl_basic_011.phpt index cf8cc63d02f..4a70e5cd9f3 100644 --- a/ext/curl/tests/curl_basic_011.phpt +++ b/ext/curl/tests/curl_basic_011.phpt @@ -21,7 +21,6 @@ curl curl_setopt($ch, CURLOPT_URL, $url); //set the url we want to use $curl_content = curl_exec($ch); - curl_close($ch); var_dump( $curl_content ); ?> diff --git a/ext/curl/tests/curl_basic_012.phpt b/ext/curl/tests/curl_basic_012.phpt index 9de92898f39..83c91f65710 100644 --- a/ext/curl/tests/curl_basic_012.phpt +++ b/ext/curl/tests/curl_basic_012.phpt @@ -21,7 +21,6 @@ curl curl_setopt($ch, CURLOPT_URL, $url); //set the url we want to use $curl_content = curl_exec($ch); - curl_close($ch); var_dump( $curl_content ); ?> diff --git a/ext/curl/tests/curl_basic_013.phpt b/ext/curl/tests/curl_basic_013.phpt index 4b0c46b5183..08ed66225b7 100644 --- a/ext/curl/tests/curl_basic_013.phpt +++ b/ext/curl/tests/curl_basic_013.phpt @@ -21,7 +21,6 @@ curl curl_setopt($ch, CURLOPT_URL, $url); //set the url we want to use $curl_content = curl_exec($ch); - curl_close($ch); var_dump( $curl_content ); ?> diff --git a/ext/curl/tests/curl_basic_019.phpt b/ext/curl/tests/curl_basic_019.phpt index 20bddd87210..62b519f790f 100644 --- a/ext/curl/tests/curl_basic_019.phpt +++ b/ext/curl/tests/curl_basic_019.phpt @@ -16,7 +16,6 @@ curl curl_exec($ch); $info = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL); var_dump($url == $info); - curl_close($ch); ?> --EXPECT-- Hello World! diff --git a/ext/curl/tests/curl_basic_020.phpt b/ext/curl/tests/curl_basic_020.phpt index d7f92d3d666..0b022d5f7a8 100644 --- a/ext/curl/tests/curl_basic_020.phpt +++ b/ext/curl/tests/curl_basic_020.phpt @@ -14,7 +14,6 @@ curl curl_setopt($ch, CURLOPT_URL, $url); curl_exec($ch); var_dump(curl_getinfo($ch, CURLINFO_HTTP_CODE)); - curl_close($ch); ?> --EXPECT-- Hello World! diff --git a/ext/curl/tests/curl_basic_021.phpt b/ext/curl/tests/curl_basic_021.phpt index d6b31f2c41a..6f67ad7fa7e 100644 --- a/ext/curl/tests/curl_basic_021.phpt +++ b/ext/curl/tests/curl_basic_021.phpt @@ -14,7 +14,6 @@ curl curl_setopt($ch, CURLOPT_URL, $url); curl_exec($ch); var_dump(curl_getinfo($ch, CURLINFO_CONTENT_TYPE)); - curl_close($ch); ?> --EXPECT-- string(24) "text/plain;charset=utf-8" diff --git a/ext/curl/tests/curl_basic_023.phpt b/ext/curl/tests/curl_basic_023.phpt index 28e6dc888ee..f7b53748582 100644 --- a/ext/curl/tests/curl_basic_023.phpt +++ b/ext/curl/tests/curl_basic_023.phpt @@ -17,7 +17,6 @@ curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_exec($ch); var_dump(CURL_HTTP_VERSION_1_1 === curl_getinfo($ch, CURLINFO_HTTP_VERSION)); -curl_close($ch); ?> --EXPECT-- bool(true) diff --git a/ext/curl/tests/curl_basic_024.phpt b/ext/curl/tests/curl_basic_024.phpt index d0e85a1204b..c075fd8747d 100644 --- a/ext/curl/tests/curl_basic_024.phpt +++ b/ext/curl/tests/curl_basic_024.phpt @@ -17,7 +17,6 @@ curl_exec($ch); var_dump(CURLPROTO_HTTP === curl_getinfo($ch, CURLINFO_PROTOCOL)); var_dump(0 === curl_getinfo($ch, CURLINFO_PROXY_SSL_VERIFYRESULT)); var_dump(curl_getinfo($ch, CURLINFO_SCHEME)); -curl_close($ch); ?> --EXPECTF-- bool(true) diff --git a/ext/curl/tests/curl_basic_025.phpt b/ext/curl/tests/curl_basic_025.phpt index d190d30a067..e333c7444e4 100644 --- a/ext/curl/tests/curl_basic_025.phpt +++ b/ext/curl/tests/curl_basic_025.phpt @@ -22,7 +22,6 @@ curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, "data"); curl_exec($ch); var_dump(curl_getinfo($ch, CURLINFO_EFFECTIVE_METHOD)); -curl_close($ch); ?> --EXPECT-- string(4) "POST" diff --git a/ext/curl/tests/curl_basic_026.phpt b/ext/curl/tests/curl_basic_026.phpt index befe9c7e69c..c8407bb40ef 100644 --- a/ext/curl/tests/curl_basic_026.phpt +++ b/ext/curl/tests/curl_basic_026.phpt @@ -21,7 +21,6 @@ curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); var_dump(curl_setopt($ch, CURLOPT_MIME_OPTIONS, CURLMIMEOPT_FORMESCAPE)); curl_exec($ch); -curl_close($ch); ?> --EXPECT-- bool(true) diff --git a/ext/curl/tests/curl_basic_027.phpt b/ext/curl/tests/curl_basic_027.phpt index d4b408859c6..9a7fd0cfafb 100644 --- a/ext/curl/tests/curl_basic_027.phpt +++ b/ext/curl/tests/curl_basic_027.phpt @@ -29,7 +29,6 @@ var_dump(curl_setopt($ch, CURLOPT_SSH_HOSTKEYFUNCTION, function ($ch, $keytype, return CURLKHMATCH_OK; })); curl_exec($ch); -curl_close($ch); ?> --EXPECT-- bool(true) diff --git a/ext/curl/tests/curl_basic_028.phpt b/ext/curl/tests/curl_basic_028.phpt index f8e79f63ead..0c9eb8b38de 100644 --- a/ext/curl/tests/curl_basic_028.phpt +++ b/ext/curl/tests/curl_basic_028.phpt @@ -25,7 +25,6 @@ var_dump(curl_setopt($ch, CURLOPT_PROTOCOLS_STR, "FilE,DICT")); var_dump(curl_setopt($ch, CURLOPT_PROTOCOLS_STR, "DICT")); var_dump(curl_setopt($ch, CURLOPT_REDIR_PROTOCOLS_STR, "HTTP")); curl_exec($ch); -curl_close($ch); ?> --EXPECTF-- Warning: curl_setopt(): The FILE protocol cannot be activated when an open_basedir is set in %s on line %d diff --git a/ext/curl/tests/curl_basic_029.phpt b/ext/curl/tests/curl_basic_029.phpt index b43e5e3897d..7e2ba34c72c 100644 --- a/ext/curl/tests/curl_basic_029.phpt +++ b/ext/curl/tests/curl_basic_029.phpt @@ -23,7 +23,6 @@ curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); var_dump(curl_setopt($ch, CURLOPT_WS_OPTIONS, 0)); var_dump(curl_setopt($ch, CURLOPT_WS_OPTIONS, CURLWS_RAW_MODE)); curl_exec($ch); -curl_close($ch); ?> --EXPECTF-- bool(%s) diff --git a/ext/curl/tests/curl_basic_030.phpt b/ext/curl/tests/curl_basic_030.phpt index 0beace9a7ea..c0285b873e1 100644 --- a/ext/curl/tests/curl_basic_030.phpt +++ b/ext/curl/tests/curl_basic_030.phpt @@ -22,7 +22,6 @@ curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); var_dump(curl_setopt($ch, CURLOPT_CA_CACHE_TIMEOUT, 1)); var_dump(curl_setopt($ch, CURLOPT_QUICK_EXIT, 1000)); curl_exec($ch); -curl_close($ch); ?> --EXPECT-- bool(true) diff --git a/ext/curl/tests/curl_close_basic.phpt b/ext/curl/tests/curl_close_basic.phpt index 5b327264c7d..11d4b3a8387 100644 --- a/ext/curl/tests/curl_close_basic.phpt +++ b/ext/curl/tests/curl_close_basic.phpt @@ -11,6 +11,7 @@ $ch = curl_init(); curl_close($ch); var_dump($ch); ?> ---EXPECT-- -object(CurlHandle)#1 (0) { +--EXPECTF-- +Deprecated: Function curl_close() is deprecated since 8.5, as it has no effect since PHP 8.0 in %s on line %d +object(CurlHandle)#%d (0) { } diff --git a/ext/curl/tests/curl_copy_handle_basic_001.phpt b/ext/curl/tests/curl_copy_handle_basic_001.phpt index 527c8183251..e118e94e2b5 100644 --- a/ext/curl/tests/curl_copy_handle_basic_001.phpt +++ b/ext/curl/tests/curl_copy_handle_basic_001.phpt @@ -21,10 +21,9 @@ curl curl_setopt($ch, CURLOPT_URL, $url); //set the url we want to use $copy = curl_copy_handle($ch); - curl_close($ch); + $ch = null; $curl_content = curl_exec($copy); - curl_close($copy); var_dump( $curl_content ); ?> diff --git a/ext/curl/tests/curl_copy_handle_basic_002.phpt b/ext/curl/tests/curl_copy_handle_basic_002.phpt index 8976433de2d..efd03a56114 100644 --- a/ext/curl/tests/curl_copy_handle_basic_002.phpt +++ b/ext/curl/tests/curl_copy_handle_basic_002.phpt @@ -22,10 +22,9 @@ curl curl_setopt($ch, CURLOPT_URL, $url); //set the url we want to use $copy = curl_copy_handle($ch); - curl_close($ch); + $ch = null; $curl_content = curl_exec($copy); - curl_close($copy); var_dump( $curl_content ); ?> diff --git a/ext/curl/tests/curl_copy_handle_basic_004.phpt b/ext/curl/tests/curl_copy_handle_basic_004.phpt index be0c4e34623..2293c4403eb 100644 --- a/ext/curl/tests/curl_copy_handle_basic_004.phpt +++ b/ext/curl/tests/curl_copy_handle_basic_004.phpt @@ -23,10 +23,9 @@ curl $curl_content = curl_exec($ch); $copy = curl_copy_handle($ch); - curl_close($ch); + $ch = null; $curl_content_copy = curl_exec($copy); - curl_close($copy); var_dump( $curl_content_copy ); ?> diff --git a/ext/curl/tests/curl_copy_handle_basic_005.phpt b/ext/curl/tests/curl_copy_handle_basic_005.phpt index 1b5f10034c2..2eff46839e4 100644 --- a/ext/curl/tests/curl_copy_handle_basic_005.phpt +++ b/ext/curl/tests/curl_copy_handle_basic_005.phpt @@ -25,10 +25,9 @@ curl $curl_content = curl_exec($ch); $copy = curl_copy_handle($ch); - curl_close($ch); + $ch = null; $curl_content_copy = curl_exec($copy); - curl_close($copy); var_dump( $curl_content_copy ); ?> diff --git a/ext/curl/tests/curl_copy_handle_basic_006.phpt b/ext/curl/tests/curl_copy_handle_basic_006.phpt index 5d350584322..aa0bff4ae9b 100644 --- a/ext/curl/tests/curl_copy_handle_basic_006.phpt +++ b/ext/curl/tests/curl_copy_handle_basic_006.phpt @@ -30,7 +30,11 @@ curl curl_close($copy); ?> ---EXPECT-- +--EXPECTF-- *** Testing curl copy handle with User Agent *** string(9) "cURL phpt" string(9) "cURL phpt" + +Deprecated: Function curl_close() is deprecated since 8.5, as it has no effect since PHP 8.0 in %s on line %d + +Deprecated: Function curl_close() is deprecated since 8.5, as it has no effect since PHP 8.0 in %s on line %d diff --git a/ext/curl/tests/curl_copy_handle_basic_007.phpt b/ext/curl/tests/curl_copy_handle_basic_007.phpt index 16be071ae00..800b4df16ad 100644 --- a/ext/curl/tests/curl_copy_handle_basic_007.phpt +++ b/ext/curl/tests/curl_copy_handle_basic_007.phpt @@ -20,10 +20,9 @@ curl curl_setopt($ch, CURLOPT_URL, $url); //set the url we want to use $copy = curl_copy_handle($ch); - curl_close($ch); + $ch = null; $curl_content = curl_exec($copy); - curl_close($copy); var_dump( $curl_content ); ?> diff --git a/ext/curl/tests/curl_copy_handle_variation3.phpt b/ext/curl/tests/curl_copy_handle_variation3.phpt index a766496d988..2e57dafa18d 100644 --- a/ext/curl/tests/curl_copy_handle_variation3.phpt +++ b/ext/curl/tests/curl_copy_handle_variation3.phpt @@ -29,7 +29,11 @@ curl_close($ch2); --EXPECTF-- bool(true) string(%d) "curl_copy_handle_variation3.txt|application/octet-stream|5" + +Deprecated: Function curl_close() is deprecated since 8.5, as it has no effect since PHP 8.0 in %s on line %d string(%d) "curl_copy_handle_variation3.txt|application/octet-stream|5" + +Deprecated: Function curl_close() is deprecated since 8.5, as it has no effect since PHP 8.0 in %s on line %d --CLEAN-- --EXPECTF-- == Testing curl_error with a fake URL == diff --git a/ext/curl/tests/curl_file_deleted_before_curl_close.phpt b/ext/curl/tests/curl_file_deleted_before_curl_close.phpt index 17a3b476f44..384be513f33 100644 --- a/ext/curl/tests/curl_file_deleted_before_curl_close.phpt +++ b/ext/curl/tests/curl_file_deleted_before_curl_close.phpt @@ -35,5 +35,6 @@ echo "Closed correctly\n"; ---EXPECT-- +--EXPECTF-- +Deprecated: Function curl_close() is deprecated since 8.5, as it has no effect since PHP 8.0 in %s on line %d Closed correctly diff --git a/ext/curl/tests/curl_file_upload.phpt b/ext/curl/tests/curl_file_upload.phpt index 75aba7d90e8..8b85190ff41 100644 --- a/ext/curl/tests/curl_file_upload.phpt +++ b/ext/curl/tests/curl_file_upload.phpt @@ -61,8 +61,6 @@ curl_setopt($ch, CURLOPT_URL, "{$host}/get.inc?test=post"); $params = array('file' => '@' . __DIR__ . '/curl_testdata1.txt'); curl_setopt($ch, CURLOPT_POSTFIELDS, $params); var_dump(curl_exec($ch)); - -curl_close($ch); ?> --EXPECTF-- string(%d) "curl_testdata1.txt|application/octet-stream|6" diff --git a/ext/curl/tests/curl_file_upload_stream.phpt b/ext/curl/tests/curl_file_upload_stream.phpt index 7a99eac518d..967e711bc48 100644 --- a/ext/curl/tests/curl_file_upload_stream.phpt +++ b/ext/curl/tests/curl_file_upload_stream.phpt @@ -17,7 +17,6 @@ $params = array('file' => $file); var_dump(curl_setopt($ch, CURLOPT_POSTFIELDS, $params)); var_dump(curl_exec($ch)); -curl_close($ch); ?> --EXPECT-- bool(true) diff --git a/ext/curl/tests/curl_ftp_pasv.phpt b/ext/curl/tests/curl_ftp_pasv.phpt index f8fddd574cb..59937cf7a62 100644 --- a/ext/curl/tests/curl_ftp_pasv.phpt +++ b/ext/curl/tests/curl_ftp_pasv.phpt @@ -50,8 +50,6 @@ if (false === getenv('PHP_CURL_FTP_REMOTE_PASSWD')) exit("skip PHP_CURL_FTP_REM $result = curl_exec ( $ch ); var_dump ( $result ); - curl_close ( $ch ); - ?> --EXPECT-- bool(true) diff --git a/ext/curl/tests/curl_getinfo_CURLINFO_CONN_ID.phpt b/ext/curl/tests/curl_getinfo_CURLINFO_CONN_ID.phpt new file mode 100644 index 00000000000..4a90b0a3c52 --- /dev/null +++ b/ext/curl/tests/curl_getinfo_CURLINFO_CONN_ID.phpt @@ -0,0 +1,146 @@ +--TEST-- +Curlinfo CURLINFO_CONN_ID +--EXTENSIONS-- +curl +--SKIPIF-- += 8.2.0"); +?> +--FILE-- +0); + +foreach([$ch1, $ch2] as $key => $ch) { + $result = curl_multi_getcontent($ch); + $info = curl_getinfo($ch); + var_dump(isset($info['conn_id'])); + var_dump(is_int($info['conn_id'])); + var_dump(curl_getinfo($ch, CURLINFO_CONN_ID) === $info['conn_id']); + var_dump(curl_getinfo($ch, CURLINFO_CONN_ID) === $key); +} + +$csh = curl_share_init(); + +curl_share_setopt($csh, CURLSHOPT_SHARE, CURL_LOCK_DATA_COOKIE); +curl_share_setopt($csh, CURLSHOPT_SHARE, CURL_LOCK_DATA_CONNECT); +curl_share_setopt($csh, CURLSHOPT_SHARE, CURL_LOCK_DATA_DNS); +curl_share_setopt($csh, CURLSHOPT_SHARE, CURL_LOCK_DATA_SSL_SESSION); + + +$ch1=curl_init(); +$ch2=curl_init(); + +foreach([$ch1, $ch2] as $ch) { + curl_setopt($ch, CURLOPT_URL, "{$host}/get.inc?test=getpost&get_param=Curl%20Handle"); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + $info = curl_getinfo($ch); + var_dump(isset($info['conn_id'])); + var_dump($info['conn_id'] === -1); +} + + +curl_setopt($ch1, CURLOPT_SHARE, $csh); + +$result = curl_exec($ch1); + +$info = curl_getinfo($ch1); +var_dump(isset($info['conn_id'])); +var_dump(is_int($info['conn_id'])); +var_dump(curl_getinfo($ch1, CURLINFO_CONN_ID) === $info['conn_id']); +var_dump(curl_getinfo($ch1, CURLINFO_CONN_ID) === 0); + +curl_setopt($ch2, CURLOPT_SHARE, $csh); + +$result = curl_exec($ch2); + +$info = curl_getinfo($ch2); +var_dump(isset($info['conn_id'])); +var_dump(is_int($info['conn_id'])); +var_dump(curl_getinfo($ch2, CURLINFO_CONN_ID) === $info['conn_id']); +var_dump(curl_getinfo($ch2, CURLINFO_CONN_ID) === 1); + +?> +--EXPECT-- +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) + diff --git a/ext/curl/tests/curl_getinfo_CURLINFO_QUEUE_TIME_T.phpt b/ext/curl/tests/curl_getinfo_CURLINFO_QUEUE_TIME_T.phpt new file mode 100644 index 00000000000..82064b93af1 --- /dev/null +++ b/ext/curl/tests/curl_getinfo_CURLINFO_QUEUE_TIME_T.phpt @@ -0,0 +1,41 @@ +--TEST-- +Curlinfo CURLINFO_QUEUE_TIME_T +--EXTENSIONS-- +curl +--SKIPIF-- += 8.6.0"); +?> +--FILE-- + 0); + +?> +--EXPECT-- +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) + diff --git a/ext/curl/tests/curl_multi_info_read.phpt b/ext/curl/tests/curl_multi_info_read.phpt index de203cbd5aa..32de1b9912e 100644 --- a/ext/curl/tests/curl_multi_info_read.phpt +++ b/ext/curl/tests/curl_multi_info_read.phpt @@ -25,10 +25,6 @@ do { while ($info = curl_multi_info_read($mh)) { var_dump($info); } - -foreach ($urls as $i => $url) { - curl_close($conn[$i]); -} ?> --EXPECTF-- array(3) { diff --git a/ext/curl/tests/curl_multi_segfault.phpt b/ext/curl/tests/curl_multi_segfault.phpt index 06fc7484cb5..025f71ee31d 100644 --- a/ext/curl/tests/curl_multi_segfault.phpt +++ b/ext/curl/tests/curl_multi_segfault.phpt @@ -47,7 +47,6 @@ if (false === getenv('PHP_CURL_FTP_REMOTE_PASSWD')) exit("skip PHP_CURL_FTP_REM var_dump(is_string(curl_multi_getcontent($ch))); curl_multi_remove_handle($cmh, $ch); - curl_close($ch); curl_multi_close($cmh); ?> --EXPECT-- diff --git a/ext/curl/tests/curl_postfields_array.phpt b/ext/curl/tests/curl_postfields_array.phpt index 4fe41eb1e0b..47635e78158 100644 --- a/ext/curl/tests/curl_postfields_array.phpt +++ b/ext/curl/tests/curl_postfields_array.phpt @@ -38,7 +38,6 @@ $ch = curl_init(); curl_setopt_array($ch, $options); $curl_content = curl_exec($ch); -curl_close($ch); $conn = stream_socket_accept($socket); echo stream_get_contents($conn); diff --git a/ext/curl/tests/curl_pushfunction.phpt b/ext/curl/tests/curl_pushfunction.phpt index 3b43dee4e25..c5d88e8dcd0 100644 --- a/ext/curl/tests/curl_pushfunction.phpt +++ b/ext/curl/tests/curl_pushfunction.phpt @@ -44,7 +44,6 @@ do { if ($handle !== null) { $responses[] = curl_multi_getcontent($info['handle']); curl_multi_remove_handle($mh, $handle); - curl_close($handle); } } } while ($info); diff --git a/ext/curl/tests/curl_pushfunction_trampoline.phpt b/ext/curl/tests/curl_pushfunction_trampoline.phpt index 55eda0de106..a4d85b3819b 100644 --- a/ext/curl/tests/curl_pushfunction_trampoline.phpt +++ b/ext/curl/tests/curl_pushfunction_trampoline.phpt @@ -48,7 +48,6 @@ do { if ($handle !== null) { $responses[] = curl_multi_getcontent($info['handle']); curl_multi_remove_handle($mh, $handle); - curl_close($handle); } } } while ($info); diff --git a/ext/curl/tests/curl_read_callback.phpt b/ext/curl/tests/curl_read_callback.phpt index 1319876ec5f..f6df70fe91d 100644 --- a/ext/curl/tests/curl_read_callback.phpt +++ b/ext/curl/tests/curl_read_callback.phpt @@ -31,7 +31,6 @@ curl_setopt($oCurl, CURLOPT_UPLOAD, 1); curl_setopt($oCurl, CURLOPT_READFUNCTION, "custom_readfunction" ); curl_setopt($oCurl, CURLOPT_INFILE, $hReadHandle ); curl_exec($oCurl); -curl_close($oCurl); fclose ($hReadHandle); diff --git a/ext/curl/tests/curl_read_trampoline.phpt b/ext/curl/tests/curl_read_trampoline.phpt index f69caebf798..38250db2805 100644 --- a/ext/curl/tests/curl_read_trampoline.phpt +++ b/ext/curl/tests/curl_read_trampoline.phpt @@ -28,7 +28,6 @@ curl_setopt($oCurl, CURLOPT_UPLOAD, 1); curl_setopt($oCurl, CURLOPT_READFUNCTION, $callback); curl_setopt($oCurl, CURLOPT_INFILE, $hReadHandle ); curl_exec($oCurl); -curl_close($oCurl); fclose ($hReadHandle); diff --git a/ext/curl/tests/curl_reset.phpt b/ext/curl/tests/curl_reset.phpt index 1a0ecfda3b7..80b883a35c4 100644 --- a/ext/curl/tests/curl_reset.phpt +++ b/ext/curl/tests/curl_reset.phpt @@ -23,8 +23,6 @@ curl_reset($ch); curl_setopt($ch, CURLOPT_URL, 'file://' . $log_file); curl_exec($ch); -curl_close($ch); - fclose($testfile_fp); echo file_get_contents($test_file); diff --git a/ext/curl/tests/curl_setopt_CURLOPT_ACCEPT_ENCODING.phpt b/ext/curl/tests/curl_setopt_CURLOPT_ACCEPT_ENCODING.phpt index c170308c2e9..a1983a22703 100644 --- a/ext/curl/tests/curl_setopt_CURLOPT_ACCEPT_ENCODING.phpt +++ b/ext/curl/tests/curl_setopt_CURLOPT_ACCEPT_ENCODING.phpt @@ -24,8 +24,6 @@ echo curl_getinfo($ch, CURLINFO_HEADER_OUT); curl_setopt($ch, CURLOPT_ACCEPT_ENCODING, NULL); curl_exec($ch); echo curl_getinfo($ch, CURLINFO_HEADER_OUT); - -curl_close($ch); ?> --EXPECTF-- GET /get.inc?test= HTTP/1.1 diff --git a/ext/curl/tests/curl_setopt_CURLOPT_FOLLOWLOCATION.phpt b/ext/curl/tests/curl_setopt_CURLOPT_FOLLOWLOCATION.phpt index 31661e2eaff..85af9b5319e 100644 --- a/ext/curl/tests/curl_setopt_CURLOPT_FOLLOWLOCATION.phpt +++ b/ext/curl/tests/curl_setopt_CURLOPT_FOLLOWLOCATION.phpt @@ -21,7 +21,6 @@ foreach ([ curl_setopt($ch,CURLOPT_RETURNTRANSFER,true); var_dump(curl_setopt($ch, CURLOPT_FOLLOWLOCATION, $follow)); var_dump(curl_exec($ch)); - curl_close($ch); } ?> --EXPECTF-- diff --git a/ext/curl/tests/curl_setopt_CURLOPT_SSL_SIGNATURE_ALGORITHMS.phpt b/ext/curl/tests/curl_setopt_CURLOPT_SSL_SIGNATURE_ALGORITHMS.phpt new file mode 100644 index 00000000000..73b4abc85bd --- /dev/null +++ b/ext/curl/tests/curl_setopt_CURLOPT_SSL_SIGNATURE_ALGORITHMS.phpt @@ -0,0 +1,40 @@ +--TEST-- +Curl option CURLOPT_SSL_SIGNATURE_ALGORITHMS +--EXTENSIONS-- +curl +--SKIPIF-- += 8.14.0"); + +include 'skipif-nocaddy.inc'; +?> +--FILE-- + +--EXPECT-- +string(4) "pong" +bool(true) +bool(false) +string(52) "failed setting signature algorithms: 'invalid-value'" +bool(true) +string(4) "pong" +bool(true) +string(4) "pong" diff --git a/ext/curl/tests/curl_setopt_array_basic.phpt b/ext/curl/tests/curl_setopt_array_basic.phpt index 361bb35f681..eb6f547029f 100644 --- a/ext/curl/tests/curl_setopt_array_basic.phpt +++ b/ext/curl/tests/curl_setopt_array_basic.phpt @@ -43,7 +43,6 @@ ob_start(); // start output buffering curl_setopt_array($ch, $options); $returnContent = curl_exec($ch); -curl_close($ch); var_dump($returnContent); isset($tempname) and is_file($tempname) and @unlink($tempname); diff --git a/ext/curl/tests/curl_setopt_basic002.phpt b/ext/curl/tests/curl_setopt_basic002.phpt index faf7fef6e93..e5303438c07 100644 --- a/ext/curl/tests/curl_setopt_basic002.phpt +++ b/ext/curl/tests/curl_setopt_basic002.phpt @@ -41,9 +41,6 @@ fclose($handle); unset($handle); var_dump(preg_replace('/[\r\n]/', ' ', file_get_contents($temp_file))); @unlink($temp_file); - -curl_close($ch); - ?> --EXPECTF-- *** Testing curl_setopt with CURLOPT_STDERR diff --git a/ext/curl/tests/curl_setopt_basic003.phpt b/ext/curl/tests/curl_setopt_basic003.phpt index ad56e1e1f24..008162c9b47 100644 --- a/ext/curl/tests/curl_setopt_basic003.phpt +++ b/ext/curl/tests/curl_setopt_basic003.phpt @@ -24,7 +24,7 @@ try { } $curl_content = curl_exec($ch); -curl_close($ch); +$ch = null; var_dump( $curl_content ); @@ -36,7 +36,7 @@ curl_setopt($ch, CURLOPT_URL, $host); $curl_content = curl_exec($ch); ob_end_clean(); -curl_close($ch); +$ch = null; var_dump( $curl_content ); ?> diff --git a/ext/curl/tests/curl_setopt_basic004.phpt b/ext/curl/tests/curl_setopt_basic004.phpt index a54ec157aa0..2ce7d9feb03 100644 --- a/ext/curl/tests/curl_setopt_basic004.phpt +++ b/ext/curl/tests/curl_setopt_basic004.phpt @@ -21,7 +21,7 @@ curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_URL, $url); $curl_content = curl_exec($ch); -curl_close($ch); +$ch = null; var_dump( $curl_content ); @@ -34,7 +34,7 @@ curl_setopt($ch, CURLOPT_URL, $url); ob_start(); $curl_content = curl_exec($ch); ob_end_clean(); -curl_close($ch); +$ch = null; var_dump( $curl_content ); ?> diff --git a/ext/curl/tests/curl_setopt_ssl.phpt b/ext/curl/tests/curl_setopt_ssl.phpt index 3f345930f62..21d9943fe60 100644 --- a/ext/curl/tests/curl_setopt_ssl.phpt +++ b/ext/curl/tests/curl_setopt_ssl.phpt @@ -82,7 +82,7 @@ try { $response = curl_exec($ch); check_response($response, $clientCertSubject); check_error($ch); - curl_close($ch); + $ch = null; echo "\n"; echo "case 2: empty client cert and key from string\n"; @@ -96,7 +96,7 @@ try { $response = curl_exec($ch); check_response($response, $clientCertSubject); check_error($ch); - curl_close($ch); + $ch = null; echo "\n"; echo "case 3: client cert and empty key from string\n"; @@ -110,7 +110,7 @@ try { $response = curl_exec($ch); check_response($response, $clientCertSubject); check_error($ch); - curl_close($ch); + $ch = null; echo "\n"; echo "case 4: client cert and key from file\n"; @@ -124,7 +124,7 @@ try { $response = curl_exec($ch); check_response($response, $clientCertSubject); check_error($ch); - curl_close($ch); + $ch = null; echo "\n"; echo "case 5: issuer cert from file\n"; @@ -140,7 +140,7 @@ try { $response = curl_exec($ch); check_response($response, $clientCertSubject); check_error($ch); - curl_close($ch); + $ch = null; echo "\n"; echo "case 6: issuer cert from string\n"; @@ -156,7 +156,7 @@ try { $response = curl_exec($ch); check_response($response, $clientCertSubject); check_error($ch); - curl_close($ch); + $ch = null; echo "\n"; echo "case 7: empty issuer cert from string\n"; @@ -172,7 +172,7 @@ try { $response = curl_exec($ch); check_response($response, $clientCertSubject); check_error($ch); - curl_close($ch); + $ch = null; } finally { // clean up server process diff --git a/ext/curl/tests/curl_share_close_basic001.phpt b/ext/curl/tests/curl_share_close_basic001.phpt index a9c14b5ead5..9e1827445a0 100644 --- a/ext/curl/tests/curl_share_close_basic001.phpt +++ b/ext/curl/tests/curl_share_close_basic001.phpt @@ -13,8 +13,10 @@ curl_share_close($sh); var_dump($sh); ?> ---EXPECT-- +--EXPECTF-- object(CurlShareHandle)#1 (0) { } + +Deprecated: Function curl_share_close() is deprecated since 8.5, as it has no effect since PHP 8.0 in %s on line %d object(CurlShareHandle)#1 (0) { } diff --git a/ext/curl/tests/curl_ssh_hostkey_trampoline.phpt b/ext/curl/tests/curl_ssh_hostkey_trampoline.phpt index 84ce8eb8511..45dd2a6b276 100644 --- a/ext/curl/tests/curl_ssh_hostkey_trampoline.phpt +++ b/ext/curl/tests/curl_ssh_hostkey_trampoline.phpt @@ -33,8 +33,6 @@ var_dump($host); curl_setopt($ch, CURLOPT_URL, $url); var_dump(curl_setopt($ch, CURLOPT_SSH_HOSTKEYFUNCTION, $callback)); curl_exec($ch); -curl_close($ch); - ?> --EXPECT-- Trampoline for trampoline diff --git a/ext/curl/tests/curl_upkeep_001.phpt b/ext/curl/tests/curl_upkeep_001.phpt index f0680e5cbbf..77ce4d77130 100644 --- a/ext/curl/tests/curl_upkeep_001.phpt +++ b/ext/curl/tests/curl_upkeep_001.phpt @@ -22,7 +22,6 @@ if (curl_exec($ch)) { usleep(300); var_dump(curl_upkeep($ch)); } -curl_close($ch); ?> --EXPECT-- bool(true) diff --git a/ext/curl/tests/curl_write_callback.phpt b/ext/curl/tests/curl_write_callback.phpt index 63f1a3da54a..308ee98bb09 100644 --- a/ext/curl/tests/curl_write_callback.phpt +++ b/ext/curl/tests/curl_write_callback.phpt @@ -26,7 +26,6 @@ $ch = curl_init(); curl_setopt($ch, CURLOPT_WRITEFUNCTION, 'curl_callback'); curl_setopt($ch, CURLOPT_URL, 'file://' . $log_file); curl_exec($ch); -curl_close($ch); // cleanup unlink($log_file); diff --git a/ext/curl/tests/curl_write_file.phpt b/ext/curl/tests/curl_write_file.phpt index b5610222ba1..eba648c0c5f 100644 --- a/ext/curl/tests/curl_write_file.phpt +++ b/ext/curl/tests/curl_write_file.phpt @@ -23,7 +23,6 @@ $ch = curl_init(); curl_setopt($ch, CURLOPT_FILE, $testfile_fp); curl_setopt($ch, CURLOPT_URL, 'file://' . $log_file); curl_exec($ch); -curl_close($ch); fclose($testfile_fp); diff --git a/ext/curl/tests/curl_write_return.phpt b/ext/curl/tests/curl_write_return.phpt index 4f0269c2f1e..bb6c9364bde 100644 --- a/ext/curl/tests/curl_write_return.phpt +++ b/ext/curl/tests/curl_write_return.phpt @@ -21,7 +21,6 @@ $ch = curl_init(); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_URL, 'file://' . $log_file); $result = curl_exec($ch); -curl_close($ch); echo $result; diff --git a/ext/curl/tests/curl_write_stdout.phpt b/ext/curl/tests/curl_write_stdout.phpt index b3a2e43516f..a23f78eb807 100644 --- a/ext/curl/tests/curl_write_stdout.phpt +++ b/ext/curl/tests/curl_write_stdout.phpt @@ -20,7 +20,6 @@ $ch = curl_init(); curl_setopt($ch, CURLOPT_FILE, STDOUT); curl_setopt($ch, CURLOPT_URL, 'file://' . $log_file); curl_exec($ch); -curl_close($ch); // cleanup unlink($log_file); diff --git a/ext/curl/tests/curl_write_trampoline.phpt b/ext/curl/tests/curl_write_trampoline.phpt index 8d604bc7bd4..292cec05109 100644 --- a/ext/curl/tests/curl_write_trampoline.phpt +++ b/ext/curl/tests/curl_write_trampoline.phpt @@ -24,7 +24,6 @@ $ch = curl_init(); curl_setopt($ch, CURLOPT_WRITEFUNCTION, $callback); curl_setopt($ch, CURLOPT_URL, 'file://' . $log_file); curl_exec($ch); -curl_close($ch); ?> --CLEAN-- diff --git a/ext/curl/tests/curl_writeheader_callback.phpt b/ext/curl/tests/curl_writeheader_callback.phpt index 3b9b10d02f2..e0994c1d023 100644 --- a/ext/curl/tests/curl_writeheader_callback.phpt +++ b/ext/curl/tests/curl_writeheader_callback.phpt @@ -24,8 +24,6 @@ curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_HEADERFUNCTION, 'curl_header_callback'); curl_setopt($ch, CURLOPT_URL, $host); curl_exec($ch); -curl_close($ch); - ?> --EXPECTF-- HTTP/1.1 %d %s diff --git a/ext/curl/tests/skipif-nocaddy.inc b/ext/curl/tests/skipif-nocaddy.inc index ae5442ff28e..98ffe2a9888 100644 --- a/ext/curl/tests/skipif-nocaddy.inc +++ b/ext/curl/tests/skipif-nocaddy.inc @@ -6,8 +6,6 @@ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); $body = curl_exec($ch); -curl_close($ch); - if ($body !== "Caddy is up and running") { die("skip test needs Caddy"); } diff --git a/ext/date/config0.m4 b/ext/date/config0.m4 index 9091803edfa..c78fcb78e15 100644 --- a/ext/date/config0.m4 +++ b/ext/date/config0.m4 @@ -5,16 +5,14 @@ dnl Check for strtoll, atoll AC_CHECK_FUNCS([strtoll atoll]) AX_CHECK_COMPILE_FLAG([-Wno-implicit-fallthrough], - [PHP_DATE_CFLAGS="$PHP_DATE_CFLAGS -Wno-implicit-fallthrough"],, - [-Werror]) + [PHP_DATE_CFLAGS="$PHP_DATE_CFLAGS -Wno-implicit-fallthrough"]) PHP_DATE_CFLAGS="$PHP_DATE_CFLAGS -DHAVE_TIMELIB_CONFIG_H=1" PHP_TIMELIB_CFLAGS="$PHP_DATE_CFLAGS" PHP_DATE_CFLAGS="$PHP_DATE_CFLAGS -I@ext_builddir@/lib -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1" AX_CHECK_COMPILE_FLAG([-fwrapv], - [PHP_TIMELIB_CFLAGS="$PHP_TIMELIB_CFLAGS -fwrapv"],, - [-Werror]) + [PHP_TIMELIB_CFLAGS="$PHP_TIMELIB_CFLAGS -fwrapv"]) timelib_sources="lib/astro.c lib/dow.c lib/parse_date.c lib/parse_tz.c lib/parse_posix.c lib/timelib.c lib/tm2unixtime.c lib/unixtime2tm.c lib/parse_iso_intervals.c lib/interval.c" diff --git a/ext/date/php_date.c b/ext/date/php_date.c index ae7f62fb8f7..fd4dc05a7ea 100644 --- a/ext/date/php_date.c +++ b/ext/date/php_date.c @@ -3968,48 +3968,38 @@ PHP_FUNCTION(date_diff) } /* }}} */ -static bool timezone_initialize(php_timezone_obj *tzobj, const char *tz, size_t tz_len, char **warning_message) /* {{{ */ +static bool timezone_initialize(php_timezone_obj *tzobj, const zend_string *tz_zstr, char **warning_message) /* {{{ */ { - timelib_time *dummy_t = ecalloc(1, sizeof(timelib_time)); + timelib_time dummy_t = {0}; int dst, not_found; - const char *orig_tz = tz; + const char *tz = ZSTR_VAL(tz_zstr); - if (strlen(tz) != tz_len) { + ZEND_ASSERT(!zend_str_has_nul_byte(tz_zstr) && "timezone should have been checked to not have null bytes"); + + dummy_t.z = timelib_parse_zone(&tz, &dst, &dummy_t, ¬_found, DATE_TIMEZONEDB, php_date_parse_tzfile_wrapper); + if ((dummy_t.z >= (100 * 60 * 60)) || (dummy_t.z <= (-100 * 60 * 60))) { if (warning_message) { - spprintf(warning_message, 0, "Timezone must not contain null bytes"); + spprintf(warning_message, 0, "Timezone offset is out of range (%s)", ZSTR_VAL(tz_zstr)); } - efree(dummy_t); + timelib_free(dummy_t.tz_abbr); return false; } - - dummy_t->z = timelib_parse_zone(&tz, &dst, dummy_t, ¬_found, DATE_TIMEZONEDB, php_date_parse_tzfile_wrapper); - if ((dummy_t->z >= (100 * 60 * 60)) || (dummy_t->z <= (-100 * 60 * 60))) { - if (warning_message) { - spprintf(warning_message, 0, "Timezone offset is out of range (%s)", orig_tz); - } - timelib_free(dummy_t->tz_abbr); - efree(dummy_t); - return false; - } - dummy_t->dst = dst; + dummy_t.dst = dst; if (!not_found && (*tz != '\0')) { if (warning_message) { - spprintf(warning_message, 0, "Unknown or bad timezone (%s)", orig_tz); + spprintf(warning_message, 0, "Unknown or bad timezone (%s)", ZSTR_VAL(tz_zstr)); } - timelib_free(dummy_t->tz_abbr); - efree(dummy_t); + timelib_free(dummy_t.tz_abbr); return false; } if (not_found) { if (warning_message) { - spprintf(warning_message, 0, "Unknown or bad timezone (%s)", orig_tz); + spprintf(warning_message, 0, "Unknown or bad timezone (%s)", ZSTR_VAL(tz_zstr)); } - efree(dummy_t); return false; } else { - set_timezone_from_timelib_time(tzobj, dummy_t); - timelib_free(dummy_t->tz_abbr); - efree(dummy_t); + set_timezone_from_timelib_time(tzobj, &dummy_t); + timelib_free(dummy_t.tz_abbr); return true; } } /* }}} */ @@ -4026,7 +4016,7 @@ PHP_FUNCTION(timezone_open) ZEND_PARSE_PARAMETERS_END(); tzobj = Z_PHPTIMEZONE_P(php_date_instantiate(date_ce_timezone, return_value)); - if (!timezone_initialize(tzobj, ZSTR_VAL(tz), ZSTR_LEN(tz), &warning_message)) { + if (!timezone_initialize(tzobj, tz, &warning_message)) { php_error_docref(NULL, E_WARNING, "%s", warning_message); efree(warning_message); zval_ptr_dtor(return_value); @@ -4047,7 +4037,7 @@ PHP_METHOD(DateTimeZone, __construct) ZEND_PARSE_PARAMETERS_END(); tzobj = Z_PHPTIMEZONE_P(ZEND_THIS); - if (!timezone_initialize(tzobj, ZSTR_VAL(tz), ZSTR_LEN(tz), &exception_message)) { + if (!timezone_initialize(tzobj, tz, &exception_message)) { zend_throw_exception_ex(date_ce_date_invalid_timezone_exception, 0, "DateTimeZone::__construct(): %s", exception_message); efree(exception_message); RETURN_THROWS(); @@ -4078,7 +4068,10 @@ static bool php_date_timezone_initialize_from_hash(zval **return_value, php_time if (Z_TYPE_P(z_timezone) != IS_STRING) { return false; } - return timezone_initialize(*tzobj, Z_STRVAL_P(z_timezone), Z_STRLEN_P(z_timezone), NULL); + if (UNEXPECTED(zend_str_has_nul_byte(Z_STR_P(z_timezone)))) { + return false; + } + return timezone_initialize(*tzobj, Z_STR_P(z_timezone), NULL); } /* }}} */ /* {{{ */ diff --git a/ext/date/php_date.stub.php b/ext/date/php_date.stub.php index 4f77fc9223e..6eef828b813 100644 --- a/ext/date/php_date.stub.php +++ b/ext/date/php_date.stub.php @@ -54,6 +54,7 @@ const DATE_RFC1123 = "D, d M Y H:i:s O"; * @var string * @cvalue DATE_FORMAT_RFC7231 */ +#[\Deprecated(since: '8.5', message: "as this format ignores the associated timezone and always uses GMT")] const DATE_RFC7231 = "D, d M Y H:i:s \\G\\M\\T"; /** @@ -287,7 +288,6 @@ function date_sun_info(int $timestamp, float $latitude, float $longitude): array interface DateTimeInterface { - public const string ATOM = DATE_ATOM; public const string COOKIE = DATE_COOKIE; @@ -304,6 +304,7 @@ interface DateTimeInterface public const string RFC1123 = DATE_RFC1123; + #[\Deprecated(since: '8.5', message: "as this format ignores the associated timezone and always uses GMT")] public const string RFC7231 = DATE_RFC7231; public const string RFC2822 = DATE_RFC2822; diff --git a/ext/date/php_date_arginfo.h b/ext/date/php_date_arginfo.h index a96d4cd4aa3..07a4398ef1c 100644 --- a/ext/date/php_date_arginfo.h +++ b/ext/date/php_date_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: c9dba59a68085579d18948963a979d63eecff204 */ + * Stub hash: db70e6a06d177d2cb6e4a47379c0b761b248f380 */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_strtotime, 0, 1, MAY_BE_LONG|MAY_BE_FALSE) ZEND_ARG_TYPE_INFO(0, datetime, IS_STRING, 0) @@ -798,7 +798,7 @@ static void register_php_date_symbols(int module_number) ZEND_ASSERT(strcmp(DATE_FORMAT_RFC1036, "D, d M y H:i:s O") == 0); REGISTER_STRING_CONSTANT("DATE_RFC1123", DATE_FORMAT_RFC1123, CONST_PERSISTENT); ZEND_ASSERT(strcmp(DATE_FORMAT_RFC1123, "D, d M Y H:i:s O") == 0); - REGISTER_STRING_CONSTANT("DATE_RFC7231", DATE_FORMAT_RFC7231, CONST_PERSISTENT); + zend_constant *const_DATE_RFC7231 = REGISTER_STRING_CONSTANT("DATE_RFC7231", DATE_FORMAT_RFC7231, CONST_PERSISTENT | CONST_DEPRECATED); ZEND_ASSERT(strcmp(DATE_FORMAT_RFC7231, "D, d M Y H:i:s \\G\\M\\T") == 0); REGISTER_STRING_CONSTANT("DATE_RFC2822", DATE_FORMAT_RFC2822, CONST_PERSISTENT); ZEND_ASSERT(strcmp(DATE_FORMAT_RFC2822, "D, d M Y H:i:s O") == 0); @@ -816,64 +816,53 @@ static void register_php_date_symbols(int module_number) zend_attribute *attribute_Deprecated_func_strftime_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "strftime", sizeof("strftime") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_func_strftime_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_1)); attribute_Deprecated_func_strftime_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_strftime_0_arg1; zend_string *attribute_Deprecated_func_strftime_0_arg1_str = zend_string_init("use IntlDateFormatter::format() instead", strlen("use IntlDateFormatter::format() instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_strftime_0_arg1, attribute_Deprecated_func_strftime_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_strftime_0->args[1].value, &attribute_Deprecated_func_strftime_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_strftime_0->args[1].value, attribute_Deprecated_func_strftime_0_arg1_str); attribute_Deprecated_func_strftime_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_func_gmstrftime_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "gmstrftime", sizeof("gmstrftime") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_func_gmstrftime_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_1)); attribute_Deprecated_func_gmstrftime_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_gmstrftime_0_arg1; - zend_string *attribute_Deprecated_func_gmstrftime_0_arg1_str = zend_string_init("use IntlDateFormatter::format() instead", strlen("use IntlDateFormatter::format() instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_gmstrftime_0_arg1, attribute_Deprecated_func_gmstrftime_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_gmstrftime_0->args[1].value, &attribute_Deprecated_func_gmstrftime_0_arg1); + ZVAL_STR_COPY(&attribute_Deprecated_func_gmstrftime_0->args[1].value, attribute_Deprecated_func_strftime_0_arg1_str); attribute_Deprecated_func_gmstrftime_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_func_date_sunrise_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "date_sunrise", sizeof("date_sunrise") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_func_date_sunrise_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_1)); attribute_Deprecated_func_date_sunrise_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_date_sunrise_0_arg1; zend_string *attribute_Deprecated_func_date_sunrise_0_arg1_str = zend_string_init("use date_sun_info() instead", strlen("use date_sun_info() instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_date_sunrise_0_arg1, attribute_Deprecated_func_date_sunrise_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_date_sunrise_0->args[1].value, &attribute_Deprecated_func_date_sunrise_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_date_sunrise_0->args[1].value, attribute_Deprecated_func_date_sunrise_0_arg1_str); attribute_Deprecated_func_date_sunrise_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_func_date_sunset_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "date_sunset", sizeof("date_sunset") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_func_date_sunset_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_1)); attribute_Deprecated_func_date_sunset_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_date_sunset_0_arg1; - zend_string *attribute_Deprecated_func_date_sunset_0_arg1_str = zend_string_init("use date_sun_info() instead", strlen("use date_sun_info() instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_date_sunset_0_arg1, attribute_Deprecated_func_date_sunset_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_date_sunset_0->args[1].value, &attribute_Deprecated_func_date_sunset_0_arg1); + ZVAL_STR_COPY(&attribute_Deprecated_func_date_sunset_0->args[1].value, attribute_Deprecated_func_date_sunrise_0_arg1_str); attribute_Deprecated_func_date_sunset_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + zend_attribute *attribute_Deprecated_const_DATE_RFC7231_0 = zend_add_global_constant_attribute(const_DATE_RFC7231, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + ZVAL_STR(&attribute_Deprecated_const_DATE_RFC7231_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_5)); + attribute_Deprecated_const_DATE_RFC7231_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zend_string *attribute_Deprecated_const_DATE_RFC7231_0_arg1_str = zend_string_init("as this format ignores the associated timezone and always uses GMT", strlen("as this format ignores the associated timezone and always uses GMT"), 1); + ZVAL_STR(&attribute_Deprecated_const_DATE_RFC7231_0->args[1].value, attribute_Deprecated_const_DATE_RFC7231_0_arg1_str); + attribute_Deprecated_const_DATE_RFC7231_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + zend_attribute *attribute_Deprecated_const_SUNFUNCS_RET_TIMESTAMP_0 = zend_add_global_constant_attribute(const_SUNFUNCS_RET_TIMESTAMP, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_const_SUNFUNCS_RET_TIMESTAMP_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_4)); attribute_Deprecated_const_SUNFUNCS_RET_TIMESTAMP_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_const_SUNFUNCS_RET_TIMESTAMP_0_arg1; zend_string *attribute_Deprecated_const_SUNFUNCS_RET_TIMESTAMP_0_arg1_str = zend_string_init("as date_sunrise() and date_sunset() were deprecated in 8.1", strlen("as date_sunrise() and date_sunset() were deprecated in 8.1"), 1); - ZVAL_STR(&attribute_Deprecated_const_SUNFUNCS_RET_TIMESTAMP_0_arg1, attribute_Deprecated_const_SUNFUNCS_RET_TIMESTAMP_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_const_SUNFUNCS_RET_TIMESTAMP_0->args[1].value, &attribute_Deprecated_const_SUNFUNCS_RET_TIMESTAMP_0_arg1); + ZVAL_STR(&attribute_Deprecated_const_SUNFUNCS_RET_TIMESTAMP_0->args[1].value, attribute_Deprecated_const_SUNFUNCS_RET_TIMESTAMP_0_arg1_str); attribute_Deprecated_const_SUNFUNCS_RET_TIMESTAMP_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_const_SUNFUNCS_RET_STRING_0 = zend_add_global_constant_attribute(const_SUNFUNCS_RET_STRING, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_const_SUNFUNCS_RET_STRING_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_4)); attribute_Deprecated_const_SUNFUNCS_RET_STRING_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_const_SUNFUNCS_RET_STRING_0_arg1; - zend_string *attribute_Deprecated_const_SUNFUNCS_RET_STRING_0_arg1_str = zend_string_init("as date_sunrise() and date_sunset() were deprecated in 8.1", strlen("as date_sunrise() and date_sunset() were deprecated in 8.1"), 1); - ZVAL_STR(&attribute_Deprecated_const_SUNFUNCS_RET_STRING_0_arg1, attribute_Deprecated_const_SUNFUNCS_RET_STRING_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_const_SUNFUNCS_RET_STRING_0->args[1].value, &attribute_Deprecated_const_SUNFUNCS_RET_STRING_0_arg1); + ZVAL_STR_COPY(&attribute_Deprecated_const_SUNFUNCS_RET_STRING_0->args[1].value, attribute_Deprecated_const_SUNFUNCS_RET_TIMESTAMP_0_arg1_str); attribute_Deprecated_const_SUNFUNCS_RET_STRING_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_const_SUNFUNCS_RET_DOUBLE_0 = zend_add_global_constant_attribute(const_SUNFUNCS_RET_DOUBLE, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_const_SUNFUNCS_RET_DOUBLE_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_4)); attribute_Deprecated_const_SUNFUNCS_RET_DOUBLE_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_const_SUNFUNCS_RET_DOUBLE_0_arg1; - zend_string *attribute_Deprecated_const_SUNFUNCS_RET_DOUBLE_0_arg1_str = zend_string_init("as date_sunrise() and date_sunset() were deprecated in 8.1", strlen("as date_sunrise() and date_sunset() were deprecated in 8.1"), 1); - ZVAL_STR(&attribute_Deprecated_const_SUNFUNCS_RET_DOUBLE_0_arg1, attribute_Deprecated_const_SUNFUNCS_RET_DOUBLE_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_const_SUNFUNCS_RET_DOUBLE_0->args[1].value, &attribute_Deprecated_const_SUNFUNCS_RET_DOUBLE_0_arg1); + ZVAL_STR_COPY(&attribute_Deprecated_const_SUNFUNCS_RET_DOUBLE_0->args[1].value, attribute_Deprecated_const_SUNFUNCS_RET_TIMESTAMP_0_arg1_str); attribute_Deprecated_const_SUNFUNCS_RET_DOUBLE_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); } @@ -944,7 +933,7 @@ static zend_class_entry *register_class_DateTimeInterface(void) zend_string *const_RFC7231_value_str = zend_string_init(DATE_FORMAT_RFC7231, strlen(DATE_FORMAT_RFC7231), 1); ZVAL_STR(&const_RFC7231_value, const_RFC7231_value_str); zend_string *const_RFC7231_name = zend_string_init_interned("RFC7231", sizeof("RFC7231") - 1, 1); - zend_declare_typed_class_constant(class_entry, const_RFC7231_name, &const_RFC7231_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_class_constant *const_RFC7231 = zend_declare_typed_class_constant(class_entry, const_RFC7231_name, &const_RFC7231_value, ZEND_ACC_PUBLIC|ZEND_ACC_DEPRECATED, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(const_RFC7231_name); zval const_RFC2822_value; @@ -982,6 +971,14 @@ static zend_class_entry *register_class_DateTimeInterface(void) zend_declare_typed_class_constant(class_entry, const_W3C_name, &const_W3C_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(const_W3C_name); + + zend_attribute *attribute_Deprecated_const_RFC7231_0 = zend_add_class_constant_attribute(class_entry, const_RFC7231, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + ZVAL_STR(&attribute_Deprecated_const_RFC7231_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_5)); + attribute_Deprecated_const_RFC7231_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zend_string *attribute_Deprecated_const_RFC7231_0_arg1_str = zend_string_init("as this format ignores the associated timezone and always uses GMT", strlen("as this format ignores the associated timezone and always uses GMT"), 1); + ZVAL_STR(&attribute_Deprecated_const_RFC7231_0->args[1].value, attribute_Deprecated_const_RFC7231_0_arg1_str); + attribute_Deprecated_const_RFC7231_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + return class_entry; } @@ -1008,82 +1005,64 @@ static zend_class_entry *register_class_DateTimeImmutable(zend_class_entry *clas zend_string *attribute_name_NoDiscard_func_modify_0 = zend_string_init_interned("NoDiscard", sizeof("NoDiscard") - 1, 1); zend_attribute *attribute_NoDiscard_func_modify_0 = zend_add_function_attribute(zend_hash_str_find_ptr(&class_entry->function_table, "modify", sizeof("modify") - 1), attribute_name_NoDiscard_func_modify_0, 1); zend_string_release(attribute_name_NoDiscard_func_modify_0); - zval attribute_NoDiscard_func_modify_0_arg0; zend_string *attribute_NoDiscard_func_modify_0_arg0_str = zend_string_init("as DateTimeImmutable::modify() does not modify the object itself", strlen("as DateTimeImmutable::modify() does not modify the object itself"), 1); - ZVAL_STR(&attribute_NoDiscard_func_modify_0_arg0, attribute_NoDiscard_func_modify_0_arg0_str); - ZVAL_COPY_VALUE(&attribute_NoDiscard_func_modify_0->args[0].value, &attribute_NoDiscard_func_modify_0_arg0); + ZVAL_STR(&attribute_NoDiscard_func_modify_0->args[0].value, attribute_NoDiscard_func_modify_0_arg0_str); attribute_NoDiscard_func_modify_0->args[0].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_string *attribute_name_NoDiscard_func_add_0 = zend_string_init_interned("NoDiscard", sizeof("NoDiscard") - 1, 1); zend_attribute *attribute_NoDiscard_func_add_0 = zend_add_function_attribute(zend_hash_str_find_ptr(&class_entry->function_table, "add", sizeof("add") - 1), attribute_name_NoDiscard_func_add_0, 1); zend_string_release(attribute_name_NoDiscard_func_add_0); - zval attribute_NoDiscard_func_add_0_arg0; zend_string *attribute_NoDiscard_func_add_0_arg0_str = zend_string_init("as DateTimeImmutable::add() does not modify the object itself", strlen("as DateTimeImmutable::add() does not modify the object itself"), 1); - ZVAL_STR(&attribute_NoDiscard_func_add_0_arg0, attribute_NoDiscard_func_add_0_arg0_str); - ZVAL_COPY_VALUE(&attribute_NoDiscard_func_add_0->args[0].value, &attribute_NoDiscard_func_add_0_arg0); + ZVAL_STR(&attribute_NoDiscard_func_add_0->args[0].value, attribute_NoDiscard_func_add_0_arg0_str); attribute_NoDiscard_func_add_0->args[0].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_string *attribute_name_NoDiscard_func_sub_0 = zend_string_init_interned("NoDiscard", sizeof("NoDiscard") - 1, 1); zend_attribute *attribute_NoDiscard_func_sub_0 = zend_add_function_attribute(zend_hash_str_find_ptr(&class_entry->function_table, "sub", sizeof("sub") - 1), attribute_name_NoDiscard_func_sub_0, 1); zend_string_release(attribute_name_NoDiscard_func_sub_0); - zval attribute_NoDiscard_func_sub_0_arg0; zend_string *attribute_NoDiscard_func_sub_0_arg0_str = zend_string_init("as DateTimeImmutable::sub() does not modify the object itself", strlen("as DateTimeImmutable::sub() does not modify the object itself"), 1); - ZVAL_STR(&attribute_NoDiscard_func_sub_0_arg0, attribute_NoDiscard_func_sub_0_arg0_str); - ZVAL_COPY_VALUE(&attribute_NoDiscard_func_sub_0->args[0].value, &attribute_NoDiscard_func_sub_0_arg0); + ZVAL_STR(&attribute_NoDiscard_func_sub_0->args[0].value, attribute_NoDiscard_func_sub_0_arg0_str); attribute_NoDiscard_func_sub_0->args[0].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_string *attribute_name_NoDiscard_func_settimezone_0 = zend_string_init_interned("NoDiscard", sizeof("NoDiscard") - 1, 1); zend_attribute *attribute_NoDiscard_func_settimezone_0 = zend_add_function_attribute(zend_hash_str_find_ptr(&class_entry->function_table, "settimezone", sizeof("settimezone") - 1), attribute_name_NoDiscard_func_settimezone_0, 1); zend_string_release(attribute_name_NoDiscard_func_settimezone_0); - zval attribute_NoDiscard_func_settimezone_0_arg0; zend_string *attribute_NoDiscard_func_settimezone_0_arg0_str = zend_string_init("as DateTimeImmutable::setTimezone() does not modify the object itself", strlen("as DateTimeImmutable::setTimezone() does not modify the object itself"), 1); - ZVAL_STR(&attribute_NoDiscard_func_settimezone_0_arg0, attribute_NoDiscard_func_settimezone_0_arg0_str); - ZVAL_COPY_VALUE(&attribute_NoDiscard_func_settimezone_0->args[0].value, &attribute_NoDiscard_func_settimezone_0_arg0); + ZVAL_STR(&attribute_NoDiscard_func_settimezone_0->args[0].value, attribute_NoDiscard_func_settimezone_0_arg0_str); attribute_NoDiscard_func_settimezone_0->args[0].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_string *attribute_name_NoDiscard_func_settime_0 = zend_string_init_interned("NoDiscard", sizeof("NoDiscard") - 1, 1); zend_attribute *attribute_NoDiscard_func_settime_0 = zend_add_function_attribute(zend_hash_str_find_ptr(&class_entry->function_table, "settime", sizeof("settime") - 1), attribute_name_NoDiscard_func_settime_0, 1); zend_string_release(attribute_name_NoDiscard_func_settime_0); - zval attribute_NoDiscard_func_settime_0_arg0; zend_string *attribute_NoDiscard_func_settime_0_arg0_str = zend_string_init("as DateTimeImmutable::setTime() does not modify the object itself", strlen("as DateTimeImmutable::setTime() does not modify the object itself"), 1); - ZVAL_STR(&attribute_NoDiscard_func_settime_0_arg0, attribute_NoDiscard_func_settime_0_arg0_str); - ZVAL_COPY_VALUE(&attribute_NoDiscard_func_settime_0->args[0].value, &attribute_NoDiscard_func_settime_0_arg0); + ZVAL_STR(&attribute_NoDiscard_func_settime_0->args[0].value, attribute_NoDiscard_func_settime_0_arg0_str); attribute_NoDiscard_func_settime_0->args[0].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_string *attribute_name_NoDiscard_func_setdate_0 = zend_string_init_interned("NoDiscard", sizeof("NoDiscard") - 1, 1); zend_attribute *attribute_NoDiscard_func_setdate_0 = zend_add_function_attribute(zend_hash_str_find_ptr(&class_entry->function_table, "setdate", sizeof("setdate") - 1), attribute_name_NoDiscard_func_setdate_0, 1); zend_string_release(attribute_name_NoDiscard_func_setdate_0); - zval attribute_NoDiscard_func_setdate_0_arg0; zend_string *attribute_NoDiscard_func_setdate_0_arg0_str = zend_string_init("as DateTimeImmutable::setDate() does not modify the object itself", strlen("as DateTimeImmutable::setDate() does not modify the object itself"), 1); - ZVAL_STR(&attribute_NoDiscard_func_setdate_0_arg0, attribute_NoDiscard_func_setdate_0_arg0_str); - ZVAL_COPY_VALUE(&attribute_NoDiscard_func_setdate_0->args[0].value, &attribute_NoDiscard_func_setdate_0_arg0); + ZVAL_STR(&attribute_NoDiscard_func_setdate_0->args[0].value, attribute_NoDiscard_func_setdate_0_arg0_str); attribute_NoDiscard_func_setdate_0->args[0].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_string *attribute_name_NoDiscard_func_setisodate_0 = zend_string_init_interned("NoDiscard", sizeof("NoDiscard") - 1, 1); zend_attribute *attribute_NoDiscard_func_setisodate_0 = zend_add_function_attribute(zend_hash_str_find_ptr(&class_entry->function_table, "setisodate", sizeof("setisodate") - 1), attribute_name_NoDiscard_func_setisodate_0, 1); zend_string_release(attribute_name_NoDiscard_func_setisodate_0); - zval attribute_NoDiscard_func_setisodate_0_arg0; zend_string *attribute_NoDiscard_func_setisodate_0_arg0_str = zend_string_init("as DateTimeImmutable::setISODate() does not modify the object itself", strlen("as DateTimeImmutable::setISODate() does not modify the object itself"), 1); - ZVAL_STR(&attribute_NoDiscard_func_setisodate_0_arg0, attribute_NoDiscard_func_setisodate_0_arg0_str); - ZVAL_COPY_VALUE(&attribute_NoDiscard_func_setisodate_0->args[0].value, &attribute_NoDiscard_func_setisodate_0_arg0); + ZVAL_STR(&attribute_NoDiscard_func_setisodate_0->args[0].value, attribute_NoDiscard_func_setisodate_0_arg0_str); attribute_NoDiscard_func_setisodate_0->args[0].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_string *attribute_name_NoDiscard_func_settimestamp_0 = zend_string_init_interned("NoDiscard", sizeof("NoDiscard") - 1, 1); zend_attribute *attribute_NoDiscard_func_settimestamp_0 = zend_add_function_attribute(zend_hash_str_find_ptr(&class_entry->function_table, "settimestamp", sizeof("settimestamp") - 1), attribute_name_NoDiscard_func_settimestamp_0, 1); zend_string_release(attribute_name_NoDiscard_func_settimestamp_0); - zval attribute_NoDiscard_func_settimestamp_0_arg0; zend_string *attribute_NoDiscard_func_settimestamp_0_arg0_str = zend_string_init("as DateTimeImmutable::setTimestamp() does not modify the object itself", strlen("as DateTimeImmutable::setTimestamp() does not modify the object itself"), 1); - ZVAL_STR(&attribute_NoDiscard_func_settimestamp_0_arg0, attribute_NoDiscard_func_settimestamp_0_arg0_str); - ZVAL_COPY_VALUE(&attribute_NoDiscard_func_settimestamp_0->args[0].value, &attribute_NoDiscard_func_settimestamp_0_arg0); + ZVAL_STR(&attribute_NoDiscard_func_settimestamp_0->args[0].value, attribute_NoDiscard_func_settimestamp_0_arg0_str); attribute_NoDiscard_func_settimestamp_0->args[0].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_string *attribute_name_NoDiscard_func_setmicrosecond_0 = zend_string_init_interned("NoDiscard", sizeof("NoDiscard") - 1, 1); zend_attribute *attribute_NoDiscard_func_setmicrosecond_0 = zend_add_function_attribute(zend_hash_str_find_ptr(&class_entry->function_table, "setmicrosecond", sizeof("setmicrosecond") - 1), attribute_name_NoDiscard_func_setmicrosecond_0, 1); zend_string_release(attribute_name_NoDiscard_func_setmicrosecond_0); - zval attribute_NoDiscard_func_setmicrosecond_0_arg0; zend_string *attribute_NoDiscard_func_setmicrosecond_0_arg0_str = zend_string_init("as DateTimeImmutable::setMicrosecond() does not modify the object itself", strlen("as DateTimeImmutable::setMicrosecond() does not modify the object itself"), 1); - ZVAL_STR(&attribute_NoDiscard_func_setmicrosecond_0_arg0, attribute_NoDiscard_func_setmicrosecond_0_arg0_str); - ZVAL_COPY_VALUE(&attribute_NoDiscard_func_setmicrosecond_0->args[0].value, &attribute_NoDiscard_func_setmicrosecond_0_arg0); + ZVAL_STR(&attribute_NoDiscard_func_setmicrosecond_0->args[0].value, attribute_NoDiscard_func_setmicrosecond_0_arg0_str); attribute_NoDiscard_func_setmicrosecond_0->args[0].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); return class_entry; diff --git a/ext/date/tests/DateTimeImmutable_constants.phpt b/ext/date/tests/DateTimeImmutable_constants.phpt index 16de66e89f1..c3192231916 100644 --- a/ext/date/tests/DateTimeImmutable_constants.phpt +++ b/ext/date/tests/DateTimeImmutable_constants.phpt @@ -21,7 +21,10 @@ var_dump( ); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Constant DATE_RFC7231 is deprecated since 8.5, as this format ignores the associated timezone and always uses GMT in %s on line %d + +Deprecated: Constant DateTimeInterface::RFC7231 is deprecated since 8.5, as this format ignores the associated timezone and always uses GMT in %s on line %d bool(true) bool(true) bool(true) diff --git a/ext/date/tests/DateTimeInterface_constants.phpt b/ext/date/tests/DateTimeInterface_constants.phpt index c740ea4d951..d02eddf4d68 100644 --- a/ext/date/tests/DateTimeInterface_constants.phpt +++ b/ext/date/tests/DateTimeInterface_constants.phpt @@ -21,7 +21,10 @@ var_dump( ); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Constant DATE_RFC7231 is deprecated since 8.5, as this format ignores the associated timezone and always uses GMT in %s on line %d + +Deprecated: Constant DateTimeInterface::RFC7231 is deprecated since 8.5, as this format ignores the associated timezone and always uses GMT in %s on line %d bool(true) bool(true) bool(true) diff --git a/ext/date/tests/DateTime_constants.phpt b/ext/date/tests/DateTime_constants.phpt index bca573d8f72..fada757775c 100644 --- a/ext/date/tests/DateTime_constants.phpt +++ b/ext/date/tests/DateTime_constants.phpt @@ -21,7 +21,10 @@ var_dump( ); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Constant DATE_RFC7231 is deprecated since 8.5, as this format ignores the associated timezone and always uses GMT in %s on line %d + +Deprecated: Constant DateTimeInterface::RFC7231 is deprecated since 8.5, as this format ignores the associated timezone and always uses GMT in %s on line %d bool(true) bool(true) bool(true) diff --git a/ext/date/tests/DateTime_format_basic2.phpt b/ext/date/tests/DateTime_format_basic2.phpt index 2946cf2c681..a829f9c2163 100644 --- a/ext/date/tests/DateTime_format_basic2.phpt +++ b/ext/date/tests/DateTime_format_basic2.phpt @@ -24,7 +24,7 @@ var_dump($date->format(DateTime::RSS)); var_dump($date->format(DateTime::W3C)); ?> ---EXPECT-- +--EXPECTF-- *** Testing date_format() : basic functionality - formatting constants *** string(25) "2005-07-14T22:30:41+01:00" string(34) "Thursday, 14-Jul-2005 22:30:41 BST" @@ -34,6 +34,8 @@ string(29) "Thu, 14 Jul 05 22:30:41 +0100" string(32) "Thursday, 14-Jul-05 22:30:41 BST" string(29) "Thu, 14 Jul 05 22:30:41 +0100" string(31) "Thu, 14 Jul 2005 22:30:41 +0100" + +Deprecated: Constant DateTimeInterface::RFC7231 is deprecated since 8.5, as this format ignores the associated timezone and always uses GMT in %s on line %d string(29) "Thu, 14 Jul 2005 22:30:41 GMT" string(31) "Thu, 14 Jul 2005 22:30:41 +0100" string(25) "2005-07-14T22:30:41+01:00" diff --git a/ext/date/tests/bug74080.phpt b/ext/date/tests/bug74080.phpt deleted file mode 100644 index a86c78144e6..00000000000 --- a/ext/date/tests/bug74080.phpt +++ /dev/null @@ -1,11 +0,0 @@ ---TEST-- -Bug #74080 Provide an RFC7231 date time format ---FILE-- - ---EXPECT-- -string(29) "Sat, 30 Apr 2016 17:52:13 GMT" diff --git a/ext/date/tests/date_constants.phpt b/ext/date/tests/date_constants.phpt index 27d93316655..2305ddbc312 100644 --- a/ext/date/tests/date_constants.phpt +++ b/ext/date/tests/date_constants.phpt @@ -44,7 +44,8 @@ Date constants DATE_W3C == DateTime::W3C ); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Constant DATE_RFC7231 is deprecated since 8.5, as this format ignores the associated timezone and always uses GMT in %s on line %d string(25) "2006-07-01T14:27:30+02:00" string(25) "2006-05-30T14:32:13+02:00" string(35) "Saturday, 01-Jul-2006 14:27:30 CEST" @@ -74,6 +75,10 @@ string(31) "Tue, 30 May 2006 14:32:13 +0200" string(25) "2006-07-01T14:27:30+02:00" string(25) "2006-05-30T14:32:13+02:00" + +Deprecated: Constant DATE_RFC7231 is deprecated since 8.5, as this format ignores the associated timezone and always uses GMT in %s on line %d + +Deprecated: Constant DateTimeInterface::RFC7231 is deprecated since 8.5, as this format ignores the associated timezone and always uses GMT in %s on line %d bool(true) bool(true) bool(true) diff --git a/ext/dom/element.c b/ext/dom/element.c index f0afcf07eb2..dbab9313015 100644 --- a/ext/dom/element.c +++ b/ext/dom/element.c @@ -62,7 +62,7 @@ PHP_METHOD(DOMElement, __construct) if (uri_len > 0) { errorcode = dom_check_qname(name, &localname, &prefix, uri_len, name_len); if (errorcode == 0) { - nodep = xmlNewNode (NULL, BAD_CAST localname); + nodep = xmlNewDocNode(NULL, NULL, BAD_CAST localname, NULL); if (nodep != NULL && uri != NULL) { nsptr = dom_get_ns(nodep, uri, &errorcode, prefix); xmlSetNs(nodep, nsptr); @@ -88,7 +88,7 @@ PHP_METHOD(DOMElement, __construct) php_dom_throw_error(NAMESPACE_ERR, true); RETURN_THROWS(); } - nodep = xmlNewNode(NULL, BAD_CAST name); + nodep = xmlNewDocNode(NULL, NULL, BAD_CAST name, NULL); } if (!nodep) { diff --git a/ext/dom/lexbor/selectors-adapted/selectors.c b/ext/dom/lexbor/selectors-adapted/selectors.c index e5348292f43..13feb4fc1bf 100644 --- a/ext/dom/lexbor/selectors-adapted/selectors.c +++ b/ext/dom/lexbor/selectors-adapted/selectors.c @@ -1,9 +1,9 @@ /* - * Copyright (C) 2021-2024 Alexander Borisov + * Copyright (C) 2021-2025 Alexander Borisov * * Author: Alexander Borisov * Adapted for PHP + libxml2 by: Niels Dossche - * Based on Lexbor (upstream commit b347aa4e4da4e82b1cae18989ceea1aa0278daf1) + * Based on Lexbor (upstream commit 971faf11a5f45433b9193a143e2897d8c0fd5611) */ #include @@ -35,11 +35,6 @@ static void dom_lxb_str_wrapper_release(dom_lxb_str_wrapper *wrapper) } } -static zend_always_inline bool lxb_selectors_adapted_is_matchable_child(const xmlNode *node) -{ - return CMP_NODE_TYPE(node, XML_ELEMENT_NODE); -} - static zend_always_inline bool lxb_selectors_adapted_cmp_local_name_literal(const xmlNode *node, const char *name) { return strcmp((const char *) node->name, name) == 0; @@ -181,48 +176,74 @@ static zend_always_inline void lxb_selectors_adapted_set_entry_id(lxb_selectors_ } static lxb_status_t -lxb_selectors_state_tree(lxb_selectors_t *selectors, const xmlNode *root, - const lxb_css_selector_list_t *list); +lxb_selectors_tree(lxb_selectors_t *selectors, const xmlNode *root); static lxb_status_t -lxb_selectors_state_run(lxb_selectors_t *selectors, const xmlNode *node, - const lxb_css_selector_list_t *list); +lxb_selectors_run(lxb_selectors_t *selectors, const xmlNode *node); static lxb_selectors_entry_t * lxb_selectors_state_find(lxb_selectors_t *selectors, lxb_selectors_entry_t *entry); static lxb_selectors_entry_t * -lxb_selectors_state_find_check(lxb_selectors_t *selectors, const xmlNode *node, - const lxb_css_selector_t *selector, - lxb_selectors_entry_t *entry); +lxb_selectors_state_found_check(lxb_selectors_t *selectors, + lxb_selectors_entry_t *entry); static lxb_selectors_entry_t * -lxb_selectors_state_pseudo_class_function(lxb_selectors_t *selectors, - lxb_selectors_entry_t *entry); - -static const xmlNode * -lxb_selectors_next_node(lxb_selectors_nested_t *main); - -static const xmlNode * -lxb_selectors_state_has_relative(const xmlNode *node, - const lxb_css_selector_t *selector); +lxb_selectors_state_found_check_forward(lxb_selectors_t *selectors, + lxb_selectors_entry_t *entry); static lxb_selectors_entry_t * -lxb_selectors_state_after_find_has(lxb_selectors_t *selectors, - lxb_selectors_entry_t *entry); +lxb_selectors_state_found(lxb_selectors_t *selectors, + lxb_selectors_entry_t *entry); + +static lxb_selectors_entry_t * +lxb_selectors_state_found_forward(lxb_selectors_t *selectors, + lxb_selectors_entry_t *entry); + +static lxb_selectors_entry_t * +lxb_selectors_state_not_found(lxb_selectors_t *selectors, + lxb_selectors_entry_t *entry); + +static lxb_selectors_entry_t * +lxb_selectors_state_not_found_forward(lxb_selectors_t *selectors, + lxb_selectors_entry_t *entry); + +static lxb_selectors_entry_t * +lxb_selectors_next_list(lxb_selectors_t *selectors, + lxb_selectors_entry_t *entry); + +static lxb_selectors_entry_t * +lxb_selectors_next_list_forward(lxb_selectors_t *selectors, + lxb_selectors_entry_t *entry); + +static lxb_selectors_entry_t * +lxb_selectors_make_following(lxb_selectors_t *selectors, + lxb_selectors_entry_t *entry); + +static lxb_selectors_entry_t * +lxb_selectors_make_following_forward(lxb_selectors_t *selectors, + lxb_selectors_entry_t *entry); static lxb_selectors_entry_t * lxb_selectors_state_after_find(lxb_selectors_t *selectors, lxb_selectors_entry_t *entry); +static lxb_selectors_entry_t * +lxb_selectors_state_after_not(lxb_selectors_t *selectors, + lxb_selectors_entry_t *entry); + static lxb_selectors_entry_t * lxb_selectors_state_after_nth_child(lxb_selectors_t *selectors, lxb_selectors_entry_t *entry); +static lxb_selectors_entry_t * +lxb_selectors_state_nth_child_found(lxb_selectors_t *selectors, + lxb_selectors_entry_t *entry); + static bool lxb_selectors_match(lxb_selectors_t *selectors, lxb_selectors_entry_t *entry, - const lxb_css_selector_t *selector, const xmlNode *node); + const xmlNode *node); static bool lxb_selectors_match_element(const lxb_css_selector_t *selector, @@ -244,7 +265,8 @@ lxb_selectors_pseudo_class(const lxb_css_selector_t *selector, const xmlNode *node); static bool -lxb_selectors_pseudo_class_function(const lxb_css_selector_t *selector, +lxb_selectors_pseudo_class_function(lxb_selectors_t *selectors, + const lxb_css_selector_t *selector, const xmlNode *node); static bool @@ -280,6 +302,10 @@ static lxb_status_t lxb_selectors_cb_not(const xmlNode *node, lxb_css_selector_specificity_t spec, void *ctx); +static lxb_status_t +lxb_selectors_cb_nth_ok(const xmlNode *node, + lxb_css_selector_specificity_t spec, void *ctx); + lxb_status_t lxb_selectors_init(lxb_selectors_t *selectors) @@ -319,17 +345,107 @@ lxb_selectors_destroy(lxb_selectors_t *selectors) selectors->nested = lexbor_dobject_destroy(selectors->nested, true); } +static lxb_selectors_entry_t * +lxb_selectors_state_entry_create(lxb_selectors_t *selectors, + const lxb_css_selector_t *selector, + lxb_selectors_entry_t *root, + const xmlNode *node) +{ + lxb_selectors_entry_t *entry; + lxb_css_selector_combinator_t combinator; + + combinator = selector->combinator; + + do { + selector = selector->prev; + + entry = lexbor_dobject_calloc(selectors->objs); + + entry->combinator = selector->combinator; + entry->selector = selector; + entry->node = node; + + if (root->prev != NULL) { + root->prev->next = entry; + entry->prev = root->prev; + } + + entry->next = root; + root->prev = entry; + } + while (selector->combinator == LXB_CSS_SELECTOR_COMBINATOR_CLOSE + && selector->prev != NULL); + + entry->combinator = combinator; + + return entry; +} + +static lxb_selectors_entry_t * +lxb_selectors_state_entry_create_forward(lxb_selectors_t *selectors, + const lxb_css_selector_t *selector, + lxb_selectors_entry_t *root, + const xmlNode *node) +{ + lxb_selectors_entry_t *entry; + + selector = selector->next; + + entry = lexbor_dobject_calloc(selectors->objs); + + entry->combinator = selector->combinator; + entry->selector = selector; + entry->node = node; + + entry->prev = root; + root->next = entry; + + return entry; +} + +static lxb_selectors_entry_t * +lxb_selectors_entry_make_first(lxb_selectors_t *selectors, + lxb_css_selector_t *selector) +{ + lxb_selectors_entry_t *entry, *prev; + + prev = NULL; + + do { + entry = lexbor_dobject_calloc(selectors->objs); + + entry->selector = selector; + entry->combinator = LXB_CSS_SELECTOR_COMBINATOR_CLOSE; + + if (prev != NULL) { + prev->next = entry; + entry->prev = prev; + } + + if (selector->combinator != LXB_CSS_SELECTOR_COMBINATOR_CLOSE + || selector->prev == NULL) + { + break; + } + + prev = entry; + selector = selector->prev; + } + while (true); + + return entry; +} + lxb_inline const xmlNode * lxb_selectors_descendant(lxb_selectors_t *selectors, lxb_selectors_entry_t *entry, - const lxb_css_selector_t *selector, const xmlNode *node) { node = node->parent; while (node != NULL) { if (CMP_NODE_TYPE(node, XML_ELEMENT_NODE) - && lxb_selectors_match(selectors, entry, selector, node)) + && lxb_selectors_match(selectors, entry, node)) { return node; } @@ -341,10 +457,68 @@ lxb_selectors_descendant(lxb_selectors_t *selectors, } lxb_inline const xmlNode * -lxb_selectors_close(lxb_selectors_t *selectors, lxb_selectors_entry_t *entry, - const lxb_css_selector_t *selector, const xmlNode *node) +lxb_selectors_descendant_forward(lxb_selectors_t *selectors, + lxb_selectors_entry_t *entry, + const xmlNode *node) { - if (lxb_selectors_match(selectors, entry, selector, node)) { + const xmlNode *root; + lxb_selectors_nested_t *current = selectors->current; + + if (entry->prev != NULL) { + root = entry->prev->node; + } + else { + root = current->root; + } + + do { + if (node->children != NULL) { + node = node->children; + } + else { + + next: + + while (node != root && node->next == NULL) { + node = node->parent; + } + + if (node == root) { + break; + } + + node = node->next; + } + + if (!CMP_NODE_TYPE(node, XML_ELEMENT_NODE)) { + goto next; + } + + if (lxb_selectors_match(selectors, entry, node)) { + return node; + } + } + while (node != NULL); + + return NULL; +} + +lxb_inline const xmlNode * +lxb_selectors_close(lxb_selectors_t *selectors, lxb_selectors_entry_t *entry, + const xmlNode *node) +{ + if (lxb_selectors_match(selectors, entry, node)) { + return node; + } + + return NULL; +} + +lxb_inline const xmlNode * +lxb_selectors_close_forward(lxb_selectors_t *selectors, + lxb_selectors_entry_t *entry, const xmlNode *node) +{ + if (lxb_selectors_match(selectors, entry, node)) { return node; } @@ -353,12 +527,12 @@ lxb_selectors_close(lxb_selectors_t *selectors, lxb_selectors_entry_t *entry, lxb_inline const xmlNode * lxb_selectors_child(lxb_selectors_t *selectors, lxb_selectors_entry_t *entry, - const lxb_css_selector_t *selector, const xmlNode *root) + const xmlNode *root) { root = root->parent; if (root != NULL && CMP_NODE_TYPE(root, XML_ELEMENT_NODE) - && lxb_selectors_match(selectors, entry, selector, root)) + && lxb_selectors_match(selectors, entry, root)) { return root; } @@ -366,15 +540,47 @@ lxb_selectors_child(lxb_selectors_t *selectors, lxb_selectors_entry_t *entry, return NULL; } +lxb_inline const xmlNode * +lxb_selectors_child_forward(lxb_selectors_t *selectors, + lxb_selectors_entry_t *entry, const xmlNode *root) +{ + if (entry->prev != NULL) { + if (entry->prev->node == root) { + root = root->children; + } + else { + root = root->next; + } + } + else if (selectors->current->root == root) { + root = root->children; + } + else { + root = root->next; + } + + while (root != NULL) { + if (CMP_NODE_TYPE(root, XML_ELEMENT_NODE) + && lxb_selectors_match(selectors, entry, root)) + { + return root; + } + + root = root->next; + } + + return NULL; +} + lxb_inline const xmlNode * lxb_selectors_sibling(lxb_selectors_t *selectors, lxb_selectors_entry_t *entry, - const lxb_css_selector_t *selector, const xmlNode *node) + const xmlNode *node) { node = node->prev; while (node != NULL) { if (CMP_NODE_TYPE(node, XML_ELEMENT_NODE)) { - if (lxb_selectors_match(selectors, entry, selector, node)) { + if (lxb_selectors_match(selectors, entry, node)) { return node; } @@ -387,15 +593,36 @@ lxb_selectors_sibling(lxb_selectors_t *selectors, lxb_selectors_entry_t *entry, return NULL; } +lxb_inline const xmlNode * +lxb_selectors_sibling_forward(lxb_selectors_t *selectors, + lxb_selectors_entry_t *entry, const xmlNode *node) +{ + node = node->next; + + while (node != NULL) { + if (CMP_NODE_TYPE(node, XML_ELEMENT_NODE)) { + if (lxb_selectors_match(selectors, entry, node)) { + return node; + } + + return NULL; + } + + node = node->next; + } + + return NULL; +} + lxb_inline const xmlNode * lxb_selectors_following(lxb_selectors_t *selectors, lxb_selectors_entry_t *entry, - const lxb_css_selector_t *selector, const xmlNode *node) + const xmlNode *node) { node = node->prev; while (node != NULL) { if (CMP_NODE_TYPE(node, XML_ELEMENT_NODE) && - lxb_selectors_match(selectors, entry, selector, node)) + lxb_selectors_match(selectors, entry, node)) { return node; } @@ -406,26 +633,72 @@ lxb_selectors_following(lxb_selectors_t *selectors, lxb_selectors_entry_t *entry return NULL; } +lxb_inline const xmlNode * +lxb_selectors_following_forward(lxb_selectors_t *selectors, + lxb_selectors_entry_t *entry, + const xmlNode *node) +{ + node = node->next; + + while (node != NULL) { + if (CMP_NODE_TYPE(node, XML_ELEMENT_NODE) && + lxb_selectors_match(selectors, entry, node)) + { + return node; + } + + node = node->next; + } + + return NULL; +} + +lxb_inline void +lxb_selectors_switch_to_found_check(lxb_selectors_t *selectors, + lxb_selectors_nested_t *current) +{ + if (current->forward) { + selectors->state = lxb_selectors_state_found_check_forward; + } + else { + selectors->state = lxb_selectors_state_found_check; + } +} + +lxb_inline void +lxb_selectors_switch_to_not_found(lxb_selectors_t *selectors, + lxb_selectors_nested_t *current) +{ + if (current->forward) { + selectors->state = lxb_selectors_state_not_found_forward; + } + else { + selectors->state = lxb_selectors_state_not_found; + } +} + lxb_status_t lxb_selectors_find(lxb_selectors_t *selectors, const xmlNode *root, const lxb_css_selector_list_t *list, lxb_selectors_cb_f cb, void *ctx) { - lxb_selectors_entry_t entry = {0}; + lxb_selectors_entry_t *entry; lxb_selectors_nested_t nested; - entry.combinator = LXB_CSS_SELECTOR_COMBINATOR_CLOSE; - entry.selector = list->last; + entry = lxb_selectors_entry_make_first(selectors, list->last); nested.parent = NULL; - nested.entry = &entry; + nested.entry = entry; + nested.first = entry; + nested.top = entry; nested.cb = cb; nested.ctx = ctx; + nested.forward = false; selectors->current = &nested; selectors->status = LXB_STATUS_OK; - return lxb_selectors_state_tree(selectors, root, list); + return lxb_selectors_tree(selectors, root); } lxb_status_t @@ -434,35 +707,43 @@ lxb_selectors_match_node(lxb_selectors_t *selectors, const xmlNode *node, lxb_selectors_cb_f cb, void *ctx) { lxb_status_t status; + lxb_selectors_entry_t *entry; lxb_selectors_nested_t nested; if (!CMP_NODE_TYPE(node, XML_ELEMENT_NODE)) { return LXB_STATUS_OK; } - lxb_selectors_entry_t entry = {0}; - - entry.combinator = LXB_CSS_SELECTOR_COMBINATOR_CLOSE; - entry.selector = list->last; + entry = lxb_selectors_entry_make_first(selectors, list->last); nested.parent = NULL; - nested.entry = &entry; + nested.entry = entry; + nested.first = entry; + nested.top = entry; nested.cb = cb; nested.ctx = ctx; + nested.forward = false; selectors->current = &nested; selectors->status = LXB_STATUS_OK; - status = lxb_selectors_state_run(selectors, node, list); + status = lxb_selectors_run(selectors, node); lxb_selectors_clean(selectors); return status; } +lxb_status_t +lxb_selectors_find_reverse(lxb_selectors_t *selectors, const xmlNode *root, + const lxb_css_selector_list_t *list, + lxb_selectors_cb_f cb, void *ctx) +{ + return lxb_selectors_find(selectors, root, list, cb, ctx); +} + static lxb_status_t -lxb_selectors_state_tree(lxb_selectors_t *selectors, const xmlNode *root, - const lxb_css_selector_list_t *list) +lxb_selectors_tree(lxb_selectors_t *selectors, const xmlNode *root) { lxb_status_t status; const xmlNode *node; @@ -491,7 +772,7 @@ lxb_selectors_state_tree(lxb_selectors_t *selectors, const xmlNode *root, goto next; } - status = lxb_selectors_state_run(selectors, node, list); + status = lxb_selectors_run(selectors, node); if (status != LXB_STATUS_OK) { if (status == LXB_STATUS_STOP) { break; @@ -529,32 +810,24 @@ out: } static lxb_status_t -lxb_selectors_state_run(lxb_selectors_t *selectors, const xmlNode *node, - const lxb_css_selector_list_t *list) +lxb_selectors_run(lxb_selectors_t *selectors, const xmlNode *node) { lxb_selectors_entry_t *entry; + lxb_selectors_nested_t *current = selectors->current; - entry = selectors->current->entry; + entry = current->entry; entry->node = node; + current->root = node; selectors->state = lxb_selectors_state_find; - selectors->first = entry; - -again: do { entry = selectors->state(selectors, entry); } while (entry != NULL); - if (selectors->current->parent != NULL - && selectors->status == LXB_STATUS_OK) - { - entry = selectors->current->entry; - selectors->state = selectors->current->return_state; - - goto again; - } + current->first = current->top; + current->entry = current->top; return selectors->status; } @@ -564,84 +837,28 @@ lxb_selectors_state_find(lxb_selectors_t *selectors, lxb_selectors_entry_t *entry) { const xmlNode *node; - lxb_selectors_entry_t *next; - const lxb_css_selector_t *selector; - const lxb_css_selector_anb_of_t *anb; - const lxb_css_selector_pseudo_t *pseudo; - selector = entry->selector; - - if (selector->type == LXB_CSS_SELECTOR_TYPE_PSEUDO_CLASS_FUNCTION) { - pseudo = &selector->u.pseudo; - - /* Optimizing. */ - - switch (pseudo->type) { - case LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_CHILD: - case LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_LAST_CHILD: - anb = pseudo->data; - - if (anb->of != NULL) { - break; - } - - goto godoit; - - case LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_OF_TYPE: - case LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_LAST_OF_TYPE: - goto godoit; - - default: - break; - } - - if (entry->nested == NULL) { - next = lexbor_dobject_calloc(selectors->objs); - - next->combinator = LXB_CSS_SELECTOR_COMBINATOR_CLOSE; - - entry->nested = lexbor_dobject_calloc(selectors->nested); - - entry->nested->entry = next; - entry->nested->parent = selectors->current; - } - - selectors->state = lxb_selectors_state_pseudo_class_function; - selectors->current->last = entry; - selectors->current = entry->nested; - - next = entry->nested->entry; - next->node = entry->node; - - return next; - } - -godoit: + selectors->state = lxb_selectors_state_found_check; switch (entry->combinator) { case LXB_CSS_SELECTOR_COMBINATOR_DESCENDANT: - node = lxb_selectors_descendant(selectors, entry, - selector, entry->node); + node = lxb_selectors_descendant(selectors, entry, entry->node); break; case LXB_CSS_SELECTOR_COMBINATOR_CLOSE: - node = lxb_selectors_close(selectors, entry, - selector, entry->node); + node = lxb_selectors_close(selectors, entry, entry->node); break; case LXB_CSS_SELECTOR_COMBINATOR_CHILD: - node = lxb_selectors_child(selectors, entry, - selector, entry->node); + node = lxb_selectors_child(selectors, entry, entry->node); break; case LXB_CSS_SELECTOR_COMBINATOR_SIBLING: - node = lxb_selectors_sibling(selectors, entry, - selector, entry->node); + node = lxb_selectors_sibling(selectors, entry, entry->node); break; case LXB_CSS_SELECTOR_COMBINATOR_FOLLOWING: - node = lxb_selectors_following(selectors, entry, - selector, entry->node); + node = lxb_selectors_following(selectors, entry, entry->node); break; case LXB_CSS_SELECTOR_COMBINATOR_CELL: @@ -650,526 +867,439 @@ godoit: return NULL; } - return lxb_selectors_state_find_check(selectors, node, selector, entry); + if (node == NULL) { + selectors->state = lxb_selectors_state_not_found; + } + else { + selectors->current->entry->node = node; + } + + return selectors->current->entry; } static lxb_selectors_entry_t * -lxb_selectors_state_find_check(lxb_selectors_t *selectors, const xmlNode *node, - const lxb_css_selector_t *selector, - lxb_selectors_entry_t *entry) +lxb_selectors_state_find_forward(lxb_selectors_t *selectors, + lxb_selectors_entry_t *entry) { - lxb_selectors_entry_t *next; - lxb_selectors_nested_t *current; + const xmlNode *node; - if (node == NULL) { + selectors->state = lxb_selectors_state_found_check_forward; - try_next: + switch (entry->combinator) { + case LXB_CSS_SELECTOR_COMBINATOR_DESCENDANT: + node = lxb_selectors_descendant_forward(selectors, entry, + entry->node); + break; - if (entry->next == NULL) { + case LXB_CSS_SELECTOR_COMBINATOR_CLOSE: + node = lxb_selectors_close_forward(selectors, entry, + entry->node); + break; - try_next_list: + case LXB_CSS_SELECTOR_COMBINATOR_CHILD: + node = lxb_selectors_child_forward(selectors, entry, entry->node); + break; - if (selector->list->next == NULL) { - return NULL; - } + case LXB_CSS_SELECTOR_COMBINATOR_SIBLING: + node = lxb_selectors_sibling_forward(selectors, entry, entry->node); + break; - /* - * Try the following selectors from the selector list. - */ + case LXB_CSS_SELECTOR_COMBINATOR_FOLLOWING: + node = lxb_selectors_following_forward(selectors, entry, + entry->node); + break; - if (entry->following != NULL) { - entry->following->node = entry->node; - - if (selectors->current->parent == NULL) { - selectors->first = entry->following; - } - - return entry->following; - } - - next = lexbor_dobject_calloc(selectors->objs); - - next->combinator = LXB_CSS_SELECTOR_COMBINATOR_CLOSE; - next->selector = selector->list->next->last; - next->node = entry->node; - - entry->following = next; - - if (selectors->current->parent == NULL) { - selectors->first = next; - } - - return next; - } - - do { - entry = entry->next; - - while (entry->combinator == LXB_CSS_SELECTOR_COMBINATOR_CLOSE) { - if (entry->next == NULL) { - selector = entry->selector; - goto try_next; - } - - entry = entry->next; - } - - switch (entry->combinator) { - case LXB_CSS_SELECTOR_COMBINATOR_DESCENDANT: - node = entry->node->parent; - - if (node == NULL - || !CMP_NODE_TYPE(node, XML_ELEMENT_NODE)) - { - node = NULL; - } - - break; - - case LXB_CSS_SELECTOR_COMBINATOR_FOLLOWING: - node = entry->node->prev; - break; - - case LXB_CSS_SELECTOR_COMBINATOR_SIBLING: - case LXB_CSS_SELECTOR_COMBINATOR_CHILD: - case LXB_CSS_SELECTOR_COMBINATOR_CLOSE: - node = NULL; - break; - - case LXB_CSS_SELECTOR_COMBINATOR_CELL: - default: - selectors->status = LXB_STATUS_ERROR; - return NULL; - } - } - while (node == NULL); - - entry->node = node; - - return entry; + case LXB_CSS_SELECTOR_COMBINATOR_CELL: + default: + selectors->status = LXB_STATUS_ERROR; + return NULL; } - if (selector->prev == NULL) { - current = selectors->current; + if (node == NULL) { + try_next: - selectors->status = current->cb(current->entry->node, - selector->list->specificity, - current->ctx); - - if ((selectors->options & LXB_SELECTORS_OPT_MATCH_FIRST) == 0 - && current->parent == NULL) - { - if (selectors->status == LXB_STATUS_OK) { - entry = selectors->first; - goto try_next_list; + do { + if (entry->prev == NULL) { + return lxb_selectors_next_list_forward(selectors, entry); } + + entry = entry->prev; + } + while (entry->combinator == LXB_CSS_SELECTOR_COMBINATOR_CLOSE); + + if (entry->combinator == LXB_CSS_SELECTOR_COMBINATOR_SIBLING) { + goto try_next; } + selectors->current->entry = entry; + selectors->state = lxb_selectors_state_find_forward; + } + else { + selectors->current->entry->node = node; + } + + return selectors->current->entry; +} + +lxb_inline lxb_selectors_entry_t * +lxb_selectors_done(lxb_selectors_t *selectors) +{ + lxb_selectors_nested_t *current = selectors->current; + + if (current->parent == NULL) { return NULL; } - if (entry->prev == NULL) { - next = lexbor_dobject_calloc(selectors->objs); + selectors->current = current->parent; - next->combinator = selector->combinator; - next->selector = selector->prev; - next->node = node; + return selectors->current->entry; +} - next->next = entry; - entry->prev = next; +lxb_inline lxb_selectors_entry_t * +lxb_selectors_exit(lxb_selectors_t *selectors) +{ + lxb_selectors_nested_t *current = selectors->current; - return next; + if (current->parent == NULL) { + return NULL; } + selectors->state = current->return_state; + + return current->entry; +} + +static lxb_selectors_entry_t * +lxb_selectors_state_found_check(lxb_selectors_t *selectors, + lxb_selectors_entry_t *entry) +{ + lxb_selectors_nested_t *current; + const xmlNode *node; + lxb_selectors_entry_t *prev; + const lxb_css_selector_t *selector; + + current = selectors->current; + entry = current->entry; + node = entry->node; + + if (entry->prev == NULL) { + selector = entry->selector; + + while (selector->combinator == LXB_CSS_SELECTOR_COMBINATOR_CLOSE + && selector->prev != NULL) + { + selector = selector->prev; + } + + if (selector->prev == NULL) { + return lxb_selectors_state_found(selectors, entry); + } + + prev = lxb_selectors_state_entry_create(selectors, selector, + entry, node); + current->entry = prev; + selectors->state = lxb_selectors_state_find; + + return prev; + } + + selectors->state = lxb_selectors_state_find; + + current->entry = entry->prev; entry->prev->node = node; return entry->prev; } static lxb_selectors_entry_t * -lxb_selectors_state_pseudo_class_function(lxb_selectors_t *selectors, - lxb_selectors_entry_t *entry) +lxb_selectors_state_found_check_forward(lxb_selectors_t *selectors, + lxb_selectors_entry_t *entry) { - const xmlNode *node, *base; lxb_selectors_nested_t *current; - const lxb_css_selector_list_t *list; - lxb_css_selector_anb_of_t *anb; - const lxb_css_selector_pseudo_t *pseudo; + const xmlNode *node; + lxb_selectors_entry_t *next; + const lxb_css_selector_t *selector; current = selectors->current; + entry = current->entry; + node = entry->node; - base = lxb_selectors_next_node(current); - if (base == NULL) { - goto not_found; - } + if (entry->next == NULL) { + selector = entry->selector; - pseudo = ¤t->parent->last->selector->u.pseudo; - - switch (pseudo->type) { - case LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_HAS: - list = (lxb_css_selector_list_t *) pseudo->data; - node = lxb_selectors_state_has_relative(base, list->first); - - if (node == NULL) { - selectors->current = selectors->current->parent; - entry = selectors->current->last; - - selectors->state = lxb_selectors_state_find; - - return lxb_selectors_state_find_check(selectors, NULL, - entry->selector, entry); - } - - current->root = base; - - current->entry->selector = list->last; - current->entry->node = node; - current->return_state = lxb_selectors_state_after_find_has; - current->cb = lxb_selectors_cb_ok; - current->ctx = ¤t->found; - current->found = false; - - selectors->state = lxb_selectors_state_find; - - return entry; - - case LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_CURRENT: - case LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_IS: - case LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_WHERE: - current->entry->selector = ((lxb_css_selector_list_t *) pseudo->data)->last; - current->entry->node = base; - current->return_state = lxb_selectors_state_after_find; - current->cb = lxb_selectors_cb_ok; - current->ctx = ¤t->found; - current->found = false; - - selectors->state = lxb_selectors_state_find; - - return entry; - - case LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NOT: - current->entry->selector = ((lxb_css_selector_list_t *) pseudo->data)->last; - current->entry->node = base; - current->return_state = lxb_selectors_state_after_find; - current->cb = lxb_selectors_cb_not; - current->ctx = ¤t->found; - current->found = true; - - selectors->state = lxb_selectors_state_find; - - return entry; - - case LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_CHILD: - case LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_LAST_CHILD: - anb = pseudo->data; - - current->entry->selector = anb->of->last; - current->entry->node = base; - current->return_state = lxb_selectors_state_after_nth_child; - current->cb = lxb_selectors_cb_ok; - current->ctx = ¤t->found; - current->root = base; - current->index = 0; - current->found = false; - - selectors->state = lxb_selectors_state_find; - - return entry; - - /* - * This one can only happen if the user has somehow messed up the - * selector. - */ - - case LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_OF_TYPE: - case LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_LAST_OF_TYPE: - case LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_DIR: - case LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_LANG: - case LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_COL: - case LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_LAST_COL: - default: - break; - } - -not_found: - - selectors->current = selectors->current->parent; - entry = selectors->current->last; - - selectors->state = lxb_selectors_state_find; - - return lxb_selectors_state_find_check(selectors, NULL, - entry->selector, entry); -} - -static const xmlNode * -lxb_selectors_next_node(lxb_selectors_nested_t *main) -{ - const xmlNode *node = main->entry->node; - - switch (main->parent->last->combinator) { - case LXB_CSS_SELECTOR_COMBINATOR_DESCENDANT: - case LXB_CSS_SELECTOR_COMBINATOR_CHILD: - if (node->parent == NULL - || !CMP_NODE_TYPE(node->parent, XML_ELEMENT_NODE)) - { - return NULL; - } - - return node->parent; - - case LXB_CSS_SELECTOR_COMBINATOR_CLOSE: - return node; - - case LXB_CSS_SELECTOR_COMBINATOR_SIBLING: - case LXB_CSS_SELECTOR_COMBINATOR_FOLLOWING: - node = node->prev; - break; - - default: - return NULL; - } - - while (node != NULL) { - if (CMP_NODE_TYPE(node, XML_ELEMENT_NODE)) { - break; + if (selector->next == NULL) { + return lxb_selectors_state_found_forward(selectors, entry); } - node = node->prev; + next = lxb_selectors_state_entry_create_forward(selectors, selector, + entry, node); + current->entry = next; + selectors->state = lxb_selectors_state_find_forward; + + return next; } - return node; -} + selectors->state = lxb_selectors_state_find_forward; -static const xmlNode * -lxb_selectors_state_has_relative(const xmlNode *node, - const lxb_css_selector_t *selector) -{ - const xmlNode *root = node; + current->entry = entry->next; + entry->next->node = node; - switch (selector->combinator) { - case LXB_CSS_SELECTOR_COMBINATOR_DESCENDANT: - case LXB_CSS_SELECTOR_COMBINATOR_CHILD: - node = node->children; - break; - - case LXB_CSS_SELECTOR_COMBINATOR_SIBLING: - case LXB_CSS_SELECTOR_COMBINATOR_FOLLOWING: - node = node->next; - break; - - default: - return NULL; - } - - while (node != NULL) { - if (CMP_NODE_TYPE(node, XML_ELEMENT_NODE)) { - break; - } - - while (node != root && node->next == NULL && node->parent != NULL) { - node = node->parent; - } - - if (node == root) { - return NULL; - } - - node = node->next; - } - - return node; + return entry->next; } static lxb_selectors_entry_t * -lxb_selectors_state_after_find_has(lxb_selectors_t *selectors, - lxb_selectors_entry_t *entry) +lxb_selectors_state_found(lxb_selectors_t *selectors, + lxb_selectors_entry_t *entry) { - const xmlNode *node; - lxb_selectors_entry_t *parent; lxb_selectors_nested_t *current; - - if (selectors->current->found) { - node = selectors->current->root; - - selectors->current = selectors->current->parent; - parent = selectors->current->last; - - selectors->state = lxb_selectors_state_find; - - return lxb_selectors_state_find_check(selectors, node, - parent->selector, parent); - } + const lxb_css_selector_t *selector; current = selectors->current; - node = entry->node; + selector = current->entry->selector; - switch (entry->selector->list->first->combinator) { - case LXB_CSS_SELECTOR_COMBINATOR_DESCENDANT: - if (node->children != NULL) { - node = node->children; - } - else { + selectors->state = lxb_selectors_state_find; - next: + selectors->status = current->cb(current->root, + selector->list->specificity, + current->ctx); - while (node != current->root && node->next == NULL) { - node = node->parent; - } - - if (node == current->root) { - goto failed; - } - - node = node->next; - } - - if (!CMP_NODE_TYPE(node, XML_ELEMENT_NODE)) { - goto next; - } - - break; - - case LXB_CSS_SELECTOR_COMBINATOR_CHILD: - case LXB_CSS_SELECTOR_COMBINATOR_FOLLOWING: - node = node->next; - - while (node != NULL && !CMP_NODE_TYPE(node, XML_ELEMENT_NODE)) { - node = node->next; - } - - if (node == NULL) { - goto failed; - } - - break; - - case LXB_CSS_SELECTOR_COMBINATOR_SIBLING: - goto failed; - - case LXB_CSS_SELECTOR_COMBINATOR_CLOSE: - case LXB_CSS_SELECTOR_COMBINATOR_CELL: - default: - selectors->status = LXB_STATUS_ERROR; - return NULL; + if ((selectors->options & LXB_SELECTORS_OPT_MATCH_FIRST) == 0 + && current->parent == NULL) + { + if (selectors->status == LXB_STATUS_OK) { + entry = selectors->current->first; + return lxb_selectors_next_list(selectors, entry); + } } - entry->node = node; + return lxb_selectors_done(selectors); +} + +static lxb_selectors_entry_t * +lxb_selectors_state_found_forward(lxb_selectors_t *selectors, + lxb_selectors_entry_t *entry) +{ + lxb_selectors_nested_t *current; + const lxb_css_selector_t *selector; + + current = selectors->current; + selector = current->entry->selector; + + selectors->state = lxb_selectors_state_find_forward; + + selectors->status = current->cb(current->root, + selector->list->specificity, + current->ctx); + + if ((selectors->options & LXB_SELECTORS_OPT_MATCH_FIRST) == 0 + && current->parent == NULL) + { + if (selectors->status == LXB_STATUS_OK) { + entry = selectors->current->first; + return lxb_selectors_next_list_forward(selectors, entry); + } + } + + return lxb_selectors_done(selectors); +} + + +static lxb_selectors_entry_t * +lxb_selectors_state_not_found(lxb_selectors_t *selectors, + lxb_selectors_entry_t *entry) +{ + lxb_selectors_nested_t *current; + + current = selectors->current; + entry = current->entry; + +try_next: + + if (entry->next == NULL) { + return lxb_selectors_next_list(selectors, entry); + } + + entry = entry->next; + + while (entry->combinator == LXB_CSS_SELECTOR_COMBINATOR_CLOSE) { + if (entry->next == NULL) { + goto try_next; + } + + entry = entry->next; + } + + switch (entry->combinator) { + case LXB_CSS_SELECTOR_COMBINATOR_SIBLING: + case LXB_CSS_SELECTOR_COMBINATOR_CHILD: + case LXB_CSS_SELECTOR_COMBINATOR_CLOSE: + goto try_next; + + default: + break; + } + + current->entry = entry; selectors->state = lxb_selectors_state_find; return entry; +} -failed: +static lxb_selectors_entry_t * +lxb_selectors_state_not_found_forward(lxb_selectors_t *selectors, + lxb_selectors_entry_t *entry) +{ +try_next: - selectors->current = selectors->current->parent; - parent = selectors->current->last; + if (entry->prev == NULL) { + return lxb_selectors_next_list_forward(selectors, entry); + } + + while (entry->combinator == LXB_CSS_SELECTOR_COMBINATOR_CLOSE) { + if (entry->prev == NULL) { + goto try_next; + } + + entry = entry->prev; + } + + if (entry->combinator == LXB_CSS_SELECTOR_COMBINATOR_SIBLING) { + if (entry->prev != NULL) { + entry = entry->prev; + } + + goto try_next; + } + + selectors->current->entry = entry; + selectors->state = lxb_selectors_state_find_forward; + + return entry; +} + +static lxb_selectors_entry_t * +lxb_selectors_next_list(lxb_selectors_t *selectors, + lxb_selectors_entry_t *entry) +{ + if (entry->selector->list->next == NULL) { + return lxb_selectors_exit(selectors); + } selectors->state = lxb_selectors_state_find; - return lxb_selectors_state_find_check(selectors, NULL, - parent->selector, parent); + /* + * Try the following selectors from the selector list. + */ + + return lxb_selectors_make_following(selectors, entry); } +static lxb_selectors_entry_t * +lxb_selectors_next_list_forward(lxb_selectors_t *selectors, + lxb_selectors_entry_t *entry) +{ + if (entry->selector->list->next == NULL) { + return lxb_selectors_exit(selectors); + } + + selectors->state = lxb_selectors_state_find_forward; + + /* + * Try the following selectors from the selector list. + */ + + return lxb_selectors_make_following_forward(selectors, entry); +} + +static lxb_selectors_entry_t * +lxb_selectors_make_following(lxb_selectors_t *selectors, + lxb_selectors_entry_t *entry) +{ + lxb_selectors_entry_t *next; + lxb_selectors_nested_t *current; + const lxb_css_selector_t *selector; + + selector = entry->selector; + current = selectors->current; + + if (entry->following != NULL) { + entry->following->node = current->root; + current->first = entry->following; + current->entry = entry->following; + + return entry->following; + } + + next = lxb_selectors_entry_make_first(selectors, + selector->list->next->last); + + next->node = current->root; + + entry->following = next; + current->first = next; + current->entry = next; + + return next; +} + +static lxb_selectors_entry_t * +lxb_selectors_make_following_forward(lxb_selectors_t *selectors, + lxb_selectors_entry_t *entry) +{ + lxb_selectors_entry_t *next; + lxb_selectors_nested_t *current; + const lxb_css_selector_t *selector; + + selector = entry->selector; + current = selectors->current; + + if (entry->following != NULL) { + entry->following->node = current->root; + current->first = entry->following; + current->entry = entry->following; + + return entry->following; + } + + next = lexbor_dobject_calloc(selectors->objs); + + next->selector = selector->list->next->first; + next->node = current->root; + next->combinator = next->selector->combinator; + + entry->following = next; + current->first = next; + current->entry = next; + + return next; +} static lxb_selectors_entry_t * lxb_selectors_state_after_find(lxb_selectors_t *selectors, lxb_selectors_entry_t *entry) { - const xmlNode *node; - lxb_selectors_entry_t *parent; - lxb_selectors_nested_t *current; + selectors->current = selectors->current->parent; - current = selectors->current; + lxb_selectors_switch_to_not_found(selectors, selectors->current); - if (current->found) { - node = entry->node; - - selectors->current = current->parent; - parent = selectors->current->last; - - selectors->state = lxb_selectors_state_find; - - return lxb_selectors_state_find_check(selectors, node, - parent->selector, parent); - } - - node = entry->node; - - switch (current->parent->last->combinator) { - case LXB_CSS_SELECTOR_COMBINATOR_DESCENDANT: - if (node->parent != NULL - && CMP_NODE_TYPE(node->parent, XML_ELEMENT_NODE)) - { - node = node->parent; - } - else { - node = NULL; - } - - break; - - case LXB_CSS_SELECTOR_COMBINATOR_FOLLOWING: - node = node->prev; - - while (node != NULL && !CMP_NODE_TYPE(node, XML_ELEMENT_NODE)) { - node = node->prev; - } - - break; - - case LXB_CSS_SELECTOR_COMBINATOR_CHILD: - case LXB_CSS_SELECTOR_COMBINATOR_SIBLING: - case LXB_CSS_SELECTOR_COMBINATOR_CLOSE: - node = NULL; - break; - - case LXB_CSS_SELECTOR_COMBINATOR_CELL: - default: - selectors->status = LXB_STATUS_ERROR; - return NULL; - } - - if (node == NULL) { - selectors->current = current->parent; - parent = selectors->current->last; - - selectors->state = lxb_selectors_state_find; - - return lxb_selectors_state_find_check(selectors, node, - parent->selector, parent); - } - - entry->node = node; - selectors->state = lxb_selectors_state_find; - - return entry; + return selectors->current->entry; } static lxb_selectors_entry_t * -lxb_selectors_state_after_nth_child(lxb_selectors_t *selectors, - lxb_selectors_entry_t *entry) +lxb_selectors_state_after_not(lxb_selectors_t *selectors, + lxb_selectors_entry_t *entry) { - bool found; - const xmlNode *node; - lxb_selectors_entry_t *parent; - lxb_selectors_nested_t *current; - const lxb_css_selector_t *selector; - const lxb_css_selector_pseudo_t *pseudo; + selectors->current = selectors->current->parent; - current = selectors->current; - selector = current->parent->last->selector; - pseudo = &selector->u.pseudo; + lxb_selectors_switch_to_found_check(selectors, selectors->current); - node = entry->node; - - if (current->found) { - current->index += 1; - } - else if (current->root == node) { - node = NULL; - goto done; - } + return selectors->current->entry; +} +lxb_inline const xmlNode * +lxb_selectors_state_nth_child_node(const lxb_css_selector_pseudo_t *pseudo, + const xmlNode *node) +{ if (pseudo->type == LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_CHILD) { node = node->prev; @@ -1193,46 +1323,98 @@ lxb_selectors_state_after_nth_child(lxb_selectors_t *selectors, } } - if (node == NULL) { - goto done; + return node; +} + +lxb_inline lxb_selectors_entry_t * +lxb_selectors_state_nth_child_done(lxb_selectors_t *selectors, + const lxb_css_selector_pseudo_t *pseudo, + size_t index) +{ + if (lxb_selectors_anb_calc(pseudo->data, index)) { + lxb_selectors_switch_to_found_check(selectors, selectors->current); + } + else { + lxb_selectors_switch_to_not_found(selectors, selectors->current); } - entry->node = node; - current->found = false; + return selectors->current->entry; +} + +static lxb_selectors_entry_t * +lxb_selectors_state_after_nth_child(lxb_selectors_t *selectors, + lxb_selectors_entry_t *entry) +{ + const xmlNode *node; + lxb_selectors_nested_t *current; + const lxb_css_selector_pseudo_t *pseudo; + + current = selectors->current; + + if (current->index == 0) { + selectors->state = lxb_selectors_state_not_found; + selectors->current = selectors->current->parent; + + return selectors->current->entry; + } + + pseudo = ¤t->parent->entry->selector->u.pseudo; + node = lxb_selectors_state_nth_child_node(pseudo, current->root); + + if (node == NULL) { + selectors->current = selectors->current->parent; + + return lxb_selectors_state_nth_child_done(selectors, pseudo, + current->index); + } + + current->root = node; + current->entry->node = node; + selectors->state = lxb_selectors_state_find; return entry; +} -done: +static lxb_selectors_entry_t * +lxb_selectors_state_nth_child_found(lxb_selectors_t *selectors, + lxb_selectors_entry_t *entry) +{ + const xmlNode *node; + lxb_selectors_nested_t *current; + const lxb_css_selector_pseudo_t *pseudo; - if (current->index > 0) { - found = lxb_selectors_anb_calc(pseudo->data, current->index); + current = entry->nested; + pseudo = &entry->selector->u.pseudo; + node = lxb_selectors_state_nth_child_node(pseudo, current->root); - node = (found) ? current->root : NULL; + if (node == NULL) { + return lxb_selectors_state_nth_child_done(selectors, pseudo, + current->index); } + current->root = node; + current->entry->node = node; + + selectors->current = current; selectors->state = lxb_selectors_state_find; - selectors->current = selectors->current->parent; - parent = selectors->current->last; - - return lxb_selectors_state_find_check(selectors, node, - parent->selector, parent); + return current->entry; } static bool lxb_selectors_match(lxb_selectors_t *selectors, lxb_selectors_entry_t *entry, - const lxb_css_selector_t *selector, const xmlNode *node) + const xmlNode *node) { - switch (selector->type) { + switch (entry->selector->type) { case LXB_CSS_SELECTOR_TYPE_ANY: return true; case LXB_CSS_SELECTOR_TYPE_ELEMENT: - return lxb_selectors_match_element(selector, node, entry); + return lxb_selectors_match_element(entry->selector, node, entry); case LXB_CSS_SELECTOR_TYPE_ID: - return lxb_selectors_match_id(selector, node, selectors->options & LXB_SELECTORS_OPT_QUIRKS_MODE); + return lxb_selectors_match_id(entry->selector, node, selectors->options & LXB_SELECTORS_OPT_QUIRKS_MODE); case LXB_CSS_SELECTOR_TYPE_CLASS: { const xmlAttr *dom_attr = lxb_selectors_adapted_attr(node, (const lxb_char_t *) "class"); @@ -1246,24 +1428,23 @@ lxb_selectors_match(lxb_selectors_t *selectors, lxb_selectors_entry_t *entry, dom_lxb_str_wrapper_release(&trg); return false; } - bool ret = lxb_selectors_match_class(&trg.str, - &selector->name, selectors->options & LXB_SELECTORS_OPT_QUIRKS_MODE); + &entry->selector->name, selectors->options & LXB_SELECTORS_OPT_QUIRKS_MODE); dom_lxb_str_wrapper_release(&trg); return ret; } case LXB_CSS_SELECTOR_TYPE_ATTRIBUTE: - return lxb_selectors_match_attribute(selector, node, entry); + return lxb_selectors_match_attribute(entry->selector, node, entry); case LXB_CSS_SELECTOR_TYPE_PSEUDO_CLASS: - return lxb_selectors_pseudo_class(selector, node); + return lxb_selectors_pseudo_class(entry->selector, node); case LXB_CSS_SELECTOR_TYPE_PSEUDO_CLASS_FUNCTION: - return lxb_selectors_pseudo_class_function(selector, node); - + return lxb_selectors_pseudo_class_function(selectors, + entry->selector, node); case LXB_CSS_SELECTOR_TYPE_PSEUDO_ELEMENT: - return lxb_selectors_pseudo_element(selector, node); + return lxb_selectors_pseudo_element(entry->selector, node); case LXB_CSS_SELECTOR_TYPE_PSEUDO_ELEMENT_FUNCTION: return false; @@ -1714,24 +1895,118 @@ lxb_selectors_pseudo_class(const lxb_css_selector_t *selector, return false; } +static lxb_selectors_nested_t * +lxb_selectors_nested_make(lxb_selectors_t *selectors, const xmlNode *node, + lxb_css_selector_t *selector, bool forward) +{ + lxb_selectors_entry_t *next; + lxb_selectors_entry_t *entry; + + entry = selectors->current->entry; + entry->node = node; + + if (entry->nested == NULL) { + if (!forward) { + next = lxb_selectors_entry_make_first(selectors, selector); + } + else { + next = lexbor_dobject_calloc(selectors->objs); + + next->combinator = selector->combinator; + next->selector = selector; + } + + entry->nested = lexbor_dobject_calloc(selectors->nested); + + entry->nested->top = next; + entry->nested->parent = selectors->current; + entry->nested->forward = forward; + } + + selectors->current = entry->nested; + entry->nested->entry = entry->nested->top; + entry->nested->first = entry->nested->top; + + selectors->current->root = node; + selectors->current->ctx = selectors; + + return selectors->current; +} + static bool -lxb_selectors_pseudo_class_function(const lxb_css_selector_t *selector, +lxb_selectors_pseudo_class_function(lxb_selectors_t *selectors, + const lxb_css_selector_t *selector, const xmlNode *node) { size_t index; const xmlNode *base; + lxb_selectors_nested_t *current; + const lxb_css_selector_list_t *list; + const lxb_css_selector_anb_of_t *anb; const lxb_css_selector_pseudo_t *pseudo; pseudo = &selector->u.pseudo; switch (pseudo->type) { + case LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_HAS: + list = (lxb_css_selector_list_t *) pseudo->data; + + current = lxb_selectors_nested_make(selectors, node, + list->first, true); + + current->cb = lxb_selectors_cb_ok; + current->return_state = lxb_selectors_state_after_find; + selectors->state = lxb_selectors_state_find_forward; + + break; + + case LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_CURRENT: + case LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_IS: + case LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_WHERE: + list = (lxb_css_selector_list_t *) pseudo->data; + + current = lxb_selectors_nested_make(selectors, node, list->last, + false); + + current->cb = lxb_selectors_cb_ok; + current->return_state = lxb_selectors_state_after_find; + selectors->state = lxb_selectors_state_find; + + break; + + case LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NOT: + list = (lxb_css_selector_list_t *) pseudo->data; + + current = lxb_selectors_nested_make(selectors, node, list->last, + false); + + current->cb = lxb_selectors_cb_not; + current->return_state = lxb_selectors_state_after_not; + selectors->state = lxb_selectors_state_find; + + break; + case LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_CHILD: case LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_LAST_CHILD: + anb = pseudo->data; + + if (anb->of != NULL) { + current = lxb_selectors_nested_make(selectors, node, + anb->of->last, false); + + current->return_state = lxb_selectors_state_after_nth_child; + current->cb = lxb_selectors_cb_nth_ok; + current->index = 0; + selectors->state = lxb_selectors_state_find; + + return true; + } + index = 0; if (pseudo->type == LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_CHILD) { while (node != NULL) { - if (lxb_selectors_adapted_is_matchable_child(node)) + if (CMP_NODE_TYPE(node, XML_ELEMENT_NODE)) { index++; } @@ -1741,7 +2016,7 @@ lxb_selectors_pseudo_class_function(const lxb_css_selector_t *selector, } else { while (node != NULL) { - if (lxb_selectors_adapted_is_matchable_child(node)) + if (CMP_NODE_TYPE(node, XML_ELEMENT_NODE)) { index++; } @@ -1759,7 +2034,7 @@ lxb_selectors_pseudo_class_function(const lxb_css_selector_t *selector, if (pseudo->type == LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_OF_TYPE) { while (node != NULL) { - if(lxb_selectors_adapted_is_matchable_child(node) + if(CMP_NODE_TYPE(node, XML_ELEMENT_NODE) && xmlStrEqual(node->name, base->name) && lxb_selectors_adapted_cmp_ns(node, base)) { @@ -1771,7 +2046,7 @@ lxb_selectors_pseudo_class_function(const lxb_css_selector_t *selector, } else { while (node != NULL) { - if(lxb_selectors_adapted_is_matchable_child(node) + if(CMP_NODE_TYPE(node, XML_ELEMENT_NODE) && xmlStrEqual(node->name, base->name) && lxb_selectors_adapted_cmp_ns(node, base)) { @@ -1789,10 +2064,10 @@ lxb_selectors_pseudo_class_function(const lxb_css_selector_t *selector, case LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_COL: case LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_LAST_COL: default: - break; + return false; } - return false; + return true; } static bool @@ -1843,7 +2118,7 @@ lxb_selectors_pseudo_class_disabled(const xmlNode *node) const xmlNode *fieldset = node; node = node->parent; - while (node != NULL && lxb_selectors_adapted_is_matchable_child(node)) { + while (node != NULL && CMP_NODE_TYPE(node, XML_ELEMENT_NODE)) { /* node is a disabled fieldset that is an ancestor of fieldset */ if (php_dom_ns_is_fast(node, php_dom_ns_is_html_magic_token) && lxb_selectors_adapted_cmp_local_name_literal(node, "fieldset") @@ -1887,7 +2162,7 @@ lxb_selectors_pseudo_class_first_child(const xmlNode *node) node = node->prev; while (node != NULL) { - if (lxb_selectors_adapted_is_matchable_child(node)) + if (CMP_NODE_TYPE(node, XML_ELEMENT_NODE)) { return false; } @@ -1905,7 +2180,7 @@ lxb_selectors_pseudo_class_first_of_type(const xmlNode *node) node = node->prev; while (node) { - if (lxb_selectors_adapted_is_matchable_child(node) + if (CMP_NODE_TYPE(node, XML_ELEMENT_NODE) && xmlStrEqual(node->name, root->name) && lxb_selectors_adapted_cmp_ns(node, root)) { @@ -1924,7 +2199,7 @@ lxb_selectors_pseudo_class_last_child(const xmlNode *node) node = node->next; while (node != NULL) { - if (lxb_selectors_adapted_is_matchable_child(node)) + if (CMP_NODE_TYPE(node, XML_ELEMENT_NODE)) { return false; } @@ -1942,7 +2217,7 @@ lxb_selectors_pseudo_class_last_of_type(const xmlNode *node) node = node->next; while (node) { - if (lxb_selectors_adapted_is_matchable_child(node) + if (CMP_NODE_TYPE(node, XML_ELEMENT_NODE) && xmlStrEqual(node->name, root->name) && lxb_selectors_adapted_cmp_ns(node, root)) { @@ -1997,7 +2272,10 @@ static lxb_status_t lxb_selectors_cb_ok(const xmlNode *node, lxb_css_selector_specificity_t spec, void *ctx) { - *((bool *) ctx) = true; + lxb_selectors_t *selectors = ctx; + + lxb_selectors_switch_to_found_check(selectors, selectors->current->parent); + return LXB_STATUS_OK; } @@ -2005,6 +2283,21 @@ static lxb_status_t lxb_selectors_cb_not(const xmlNode *node, lxb_css_selector_specificity_t spec, void *ctx) { - *((bool *) ctx) = false; + lxb_selectors_t *selectors = ctx; + + lxb_selectors_switch_to_not_found(selectors, selectors->current->parent); + + return LXB_STATUS_OK; +} + +static lxb_status_t +lxb_selectors_cb_nth_ok(const xmlNode *node, + lxb_css_selector_specificity_t spec, void *ctx) +{ + lxb_selectors_t *selectors = ctx; + + selectors->current->index += 1; + selectors->state = lxb_selectors_state_nth_child_found; + return LXB_STATUS_OK; } diff --git a/ext/dom/lexbor/selectors-adapted/selectors.h b/ext/dom/lexbor/selectors-adapted/selectors.h index a4aea04887f..c0f76cce3d5 100644 --- a/ext/dom/lexbor/selectors-adapted/selectors.h +++ b/ext/dom/lexbor/selectors-adapted/selectors.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2021-2024 Alexander Borisov + * Copyright (C) 2021-2025 Alexander Borisov * * Author: Alexander Borisov * Adapted for PHP libxml2 by: Niels Dossche @@ -100,11 +100,13 @@ struct lxb_selectors_nested { void *ctx; const xmlNode *root; - lxb_selectors_entry_t *last; lxb_selectors_nested_t *parent; + lxb_selectors_entry_t *first; + lxb_selectors_entry_t *top; size_t index; - bool found; + + bool forward; }; struct lxb_selectors { @@ -113,7 +115,6 @@ struct lxb_selectors { lexbor_dobject_t *nested; lxb_selectors_nested_t *current; - lxb_selectors_entry_t *first; lxb_selectors_opt_t options; lxb_status_t status; diff --git a/ext/dom/php_dom_arginfo.h b/ext/dom/php_dom_arginfo.h index af2d3f2f00f..0eddfd96469 100644 --- a/ext/dom/php_dom_arginfo.h +++ b/ext/dom/php_dom_arginfo.h @@ -1884,10 +1884,8 @@ static void register_php_dom_symbols(int module_number) zend_attribute *attribute_Deprecated_const_DOM_PHP_ERR_0 = zend_add_global_constant_attribute(const_DOM_PHP_ERR, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_const_DOM_PHP_ERR_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_4)); attribute_Deprecated_const_DOM_PHP_ERR_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_const_DOM_PHP_ERR_0_arg1; zend_string *attribute_Deprecated_const_DOM_PHP_ERR_0_arg1_str = zend_string_init("as it is no longer used", strlen("as it is no longer used"), 1); - ZVAL_STR(&attribute_Deprecated_const_DOM_PHP_ERR_0_arg1, attribute_Deprecated_const_DOM_PHP_ERR_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_const_DOM_PHP_ERR_0->args[1].value, &attribute_Deprecated_const_DOM_PHP_ERR_0_arg1); + ZVAL_STR(&attribute_Deprecated_const_DOM_PHP_ERR_0->args[1].value, attribute_Deprecated_const_DOM_PHP_ERR_0_arg1_str); attribute_Deprecated_const_DOM_PHP_ERR_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); } diff --git a/ext/dom/tests/modern/css_selectors/gh18877.phpt b/ext/dom/tests/modern/css_selectors/gh18877.phpt new file mode 100644 index 00000000000..8cab491a0dd --- /dev/null +++ b/ext/dom/tests/modern/css_selectors/gh18877.phpt @@ -0,0 +1,30 @@ +--TEST-- +GH-18877 (\Dom\HTMLDocument querySelectorAll selecting only the first when using ~ and :has) +--EXTENSIONS-- +dom +--FILE-- + + + + +
+ 1 + 2 + 3 + + +TEXT; + +$dom = \Dom\HTMLDocument::createFromString($text, options: LIBXML_NOERROR); +foreach ($dom->querySelectorAll('div:has(div) ~ *') as $node) { + var_dump($node->textContent); +} + +?> +--EXPECT-- +string(1) "1" +string(1) "2" +string(1) "3" diff --git a/ext/enchant/enchant_arginfo.h b/ext/enchant/enchant_arginfo.h index 07dba8b5328..01681072346 100644 --- a/ext/enchant/enchant_arginfo.h +++ b/ext/enchant/enchant_arginfo.h @@ -166,10 +166,8 @@ static void register_enchant_symbols(int module_number) zend_attribute *attribute_Deprecated_func_enchant_broker_free_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "enchant_broker_free", sizeof("enchant_broker_free") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_func_enchant_broker_free_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_func_enchant_broker_free_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_enchant_broker_free_0_arg1; zend_string *attribute_Deprecated_func_enchant_broker_free_0_arg1_str = zend_string_init("as EnchantBroker objects are freed automatically", strlen("as EnchantBroker objects are freed automatically"), 1); - ZVAL_STR(&attribute_Deprecated_func_enchant_broker_free_0_arg1, attribute_Deprecated_func_enchant_broker_free_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_enchant_broker_free_0->args[1].value, &attribute_Deprecated_func_enchant_broker_free_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_enchant_broker_free_0->args[1].value, attribute_Deprecated_func_enchant_broker_free_0_arg1_str); attribute_Deprecated_func_enchant_broker_free_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_func_enchant_broker_set_dict_path_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "enchant_broker_set_dict_path", sizeof("enchant_broker_set_dict_path") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 1); @@ -183,46 +181,35 @@ static void register_enchant_symbols(int module_number) zend_attribute *attribute_Deprecated_func_enchant_broker_free_dict_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "enchant_broker_free_dict", sizeof("enchant_broker_free_dict") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_func_enchant_broker_free_dict_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_func_enchant_broker_free_dict_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_enchant_broker_free_dict_0_arg1; zend_string *attribute_Deprecated_func_enchant_broker_free_dict_0_arg1_str = zend_string_init("as EnchantDictionary objects are freed automatically", strlen("as EnchantDictionary objects are freed automatically"), 1); - ZVAL_STR(&attribute_Deprecated_func_enchant_broker_free_dict_0_arg1, attribute_Deprecated_func_enchant_broker_free_dict_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_enchant_broker_free_dict_0->args[1].value, &attribute_Deprecated_func_enchant_broker_free_dict_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_enchant_broker_free_dict_0->args[1].value, attribute_Deprecated_func_enchant_broker_free_dict_0_arg1_str); attribute_Deprecated_func_enchant_broker_free_dict_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_func_enchant_dict_add_to_personal_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "enchant_dict_add_to_personal", sizeof("enchant_dict_add_to_personal") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_func_enchant_dict_add_to_personal_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_func_enchant_dict_add_to_personal_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_enchant_dict_add_to_personal_0_arg1; zend_string *attribute_Deprecated_func_enchant_dict_add_to_personal_0_arg1_str = zend_string_init("use enchant_dict_add() instead", strlen("use enchant_dict_add() instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_enchant_dict_add_to_personal_0_arg1, attribute_Deprecated_func_enchant_dict_add_to_personal_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_enchant_dict_add_to_personal_0->args[1].value, &attribute_Deprecated_func_enchant_dict_add_to_personal_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_enchant_dict_add_to_personal_0->args[1].value, attribute_Deprecated_func_enchant_dict_add_to_personal_0_arg1_str); attribute_Deprecated_func_enchant_dict_add_to_personal_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_func_enchant_dict_is_in_session_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "enchant_dict_is_in_session", sizeof("enchant_dict_is_in_session") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_func_enchant_dict_is_in_session_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_func_enchant_dict_is_in_session_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_enchant_dict_is_in_session_0_arg1; zend_string *attribute_Deprecated_func_enchant_dict_is_in_session_0_arg1_str = zend_string_init("use enchant_dict_is_added() instead", strlen("use enchant_dict_is_added() instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_enchant_dict_is_in_session_0_arg1, attribute_Deprecated_func_enchant_dict_is_in_session_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_enchant_dict_is_in_session_0->args[1].value, &attribute_Deprecated_func_enchant_dict_is_in_session_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_enchant_dict_is_in_session_0->args[1].value, attribute_Deprecated_func_enchant_dict_is_in_session_0_arg1_str); attribute_Deprecated_func_enchant_dict_is_in_session_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_const_ENCHANT_MYSPELL_0 = zend_add_global_constant_attribute(const_ENCHANT_MYSPELL, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_const_ENCHANT_MYSPELL_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_const_ENCHANT_MYSPELL_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_const_ENCHANT_MYSPELL_0_arg1; zend_string *attribute_Deprecated_const_ENCHANT_MYSPELL_0_arg1_str = zend_string_init("as enchant_broker_get_dict_path() and enchant_broker_set_dict_path() are deprecated", strlen("as enchant_broker_get_dict_path() and enchant_broker_set_dict_path() are deprecated"), 1); - ZVAL_STR(&attribute_Deprecated_const_ENCHANT_MYSPELL_0_arg1, attribute_Deprecated_const_ENCHANT_MYSPELL_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_const_ENCHANT_MYSPELL_0->args[1].value, &attribute_Deprecated_const_ENCHANT_MYSPELL_0_arg1); + ZVAL_STR(&attribute_Deprecated_const_ENCHANT_MYSPELL_0->args[1].value, attribute_Deprecated_const_ENCHANT_MYSPELL_0_arg1_str); attribute_Deprecated_const_ENCHANT_MYSPELL_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_const_ENCHANT_ISPELL_0 = zend_add_global_constant_attribute(const_ENCHANT_ISPELL, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_const_ENCHANT_ISPELL_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_const_ENCHANT_ISPELL_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_const_ENCHANT_ISPELL_0_arg1; - zend_string *attribute_Deprecated_const_ENCHANT_ISPELL_0_arg1_str = zend_string_init("as enchant_broker_get_dict_path() and enchant_broker_set_dict_path() are deprecated", strlen("as enchant_broker_get_dict_path() and enchant_broker_set_dict_path() are deprecated"), 1); - ZVAL_STR(&attribute_Deprecated_const_ENCHANT_ISPELL_0_arg1, attribute_Deprecated_const_ENCHANT_ISPELL_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_const_ENCHANT_ISPELL_0->args[1].value, &attribute_Deprecated_const_ENCHANT_ISPELL_0_arg1); + ZVAL_STR_COPY(&attribute_Deprecated_const_ENCHANT_ISPELL_0->args[1].value, attribute_Deprecated_const_ENCHANT_MYSPELL_0_arg1_str); attribute_Deprecated_const_ENCHANT_ISPELL_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); } diff --git a/ext/fileinfo/fileinfo.c b/ext/fileinfo/fileinfo.c index 143b8ba080f..baae7571549 100644 --- a/ext/fileinfo/fileinfo.c +++ b/ext/fileinfo/fileinfo.c @@ -31,10 +31,11 @@ #include "php_ini.h" #include "ext/standard/info.h" #include "ext/standard/file.h" /* needed for context stuff */ +#include "Zend/zend_attributes.h" +#include "Zend/zend_exceptions.h" #include "php_fileinfo.h" #include "fileinfo_arginfo.h" #include "fopen_wrappers.h" /* needed for is_url */ -#include "Zend/zend_exceptions.h" static zend_object_handlers finfo_object_handlers; zend_class_entry *finfo_class_entry; @@ -153,22 +154,10 @@ PHP_FUNCTION(finfo_open) } else if (file && *file) { /* user specified file, perform open_basedir checks */ if (php_check_open_basedir(file)) { - if (object) { - zend_restore_error_handling(&zeh); - if (!EG(exception)) { - zend_throw_exception(NULL, "Constructor failed", 0); - } - } - RETURN_FALSE; + goto err; } if (!expand_filepath_with_mode(file, resolved_path, NULL, 0, CWD_EXPAND)) { - if (object) { - zend_restore_error_handling(&zeh); - if (!EG(exception)) { - zend_throw_exception(NULL, "Constructor failed", 0); - } - } - RETURN_FALSE; + goto err; } file = resolved_path; } @@ -177,37 +166,35 @@ PHP_FUNCTION(finfo_open) if (magic == NULL) { php_error_docref(NULL, E_WARNING, "Invalid mode '" ZEND_LONG_FMT "'.", options); - if (object) { - zend_restore_error_handling(&zeh); - if (!EG(exception)) { - zend_throw_exception(NULL, "Constructor failed", 0); - } - } - RETURN_FALSE; + goto err; } if (magic_load(magic, file) == -1) { php_error_docref(NULL, E_WARNING, "Failed to load magic database at \"%s\"", file); magic_close(magic); - if (object) { - zend_restore_error_handling(&zeh); - if (!EG(exception)) { - zend_throw_exception(NULL, "Constructor failed", 0); - } - } - RETURN_FALSE; + goto err; } if (object) { zend_restore_error_handling(&zeh); finfo_object *obj = Z_FINFO_P(object); obj->magic = magic; + return; } else { zend_object *zobj = finfo_objects_new(finfo_class_entry); finfo_object *obj = php_finfo_fetch_object(zobj); obj->magic = magic; RETURN_OBJ(zobj); } + +err: + if (object) { + zend_restore_error_handling(&zeh); + if (!EG(exception)) { + zend_throw_exception(NULL, "Constructor failed", 0); + } + } + RETURN_FALSE; } /* }}} */ @@ -356,6 +343,13 @@ PHP_FUNCTION(finfo_buffer) RETURN_THROWS(); } + if (ZEND_NUM_ARGS() == 4 || (hasThis() && ZEND_NUM_ARGS() == 3)) { + php_error_docref(NULL, E_DEPRECATED, "The $context parameter has no effect for finfo_buffer()"); + if (UNEXPECTED(EG(exception))) { + RETURN_THROWS(); + } + } + if (!Z_FINFO_P(self)->magic) { zend_throw_error(NULL, "Invalid finfo object"); RETURN_THROWS(); diff --git a/ext/fileinfo/fileinfo.stub.php b/ext/fileinfo/fileinfo.stub.php index 2dba0fe2659..238ad7c1480 100644 --- a/ext/fileinfo/fileinfo.stub.php +++ b/ext/fileinfo/fileinfo.stub.php @@ -92,6 +92,7 @@ class finfo /** @refcount 1 */ function finfo_open(int $flags = FILEINFO_NONE, ?string $magic_database = null): finfo|false {} +#[\Deprecated(since: '8.5', message: 'as finfo objects are freed automatically')] function finfo_close(finfo $finfo): true {} function finfo_set_flags(finfo $finfo, int $flags): true {} diff --git a/ext/fileinfo/fileinfo_arginfo.h b/ext/fileinfo/fileinfo_arginfo.h index 024e7d4b6bd..ac6ba0f591f 100644 --- a/ext/fileinfo/fileinfo_arginfo.h +++ b/ext/fileinfo/fileinfo_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: d5bc322159e4af87077c07ddaca0a77803b4743a */ + * Stub hash: 311d1049e32af017b44e260a00f13830714b1e96 */ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_finfo_open, 0, 0, finfo, MAY_BE_FALSE) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, flags, IS_LONG, 0, "FILEINFO_NONE") @@ -63,7 +63,7 @@ ZEND_FUNCTION(mime_content_type); static const zend_function_entry ext_functions[] = { ZEND_FE(finfo_open, arginfo_finfo_open) - ZEND_FE(finfo_close, arginfo_finfo_close) + ZEND_RAW_FENTRY("finfo_close", zif_finfo_close, arginfo_finfo_close, ZEND_ACC_DEPRECATED, NULL, NULL) ZEND_FE(finfo_set_flags, arginfo_finfo_set_flags) ZEND_FE(finfo_file, arginfo_finfo_file) ZEND_FE(finfo_buffer, arginfo_finfo_buffer) @@ -96,6 +96,14 @@ static void register_fileinfo_symbols(int module_number) #endif REGISTER_LONG_CONSTANT("FILEINFO_APPLE", MAGIC_APPLE, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("FILEINFO_EXTENSION", MAGIC_EXTENSION, CONST_PERSISTENT); + + + zend_attribute *attribute_Deprecated_func_finfo_close_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "finfo_close", sizeof("finfo_close") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + ZVAL_STR(&attribute_Deprecated_func_finfo_close_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_5)); + attribute_Deprecated_func_finfo_close_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zend_string *attribute_Deprecated_func_finfo_close_0_arg1_str = zend_string_init("as finfo objects are freed automatically", strlen("as finfo objects are freed automatically"), 1); + ZVAL_STR(&attribute_Deprecated_func_finfo_close_0->args[1].value, attribute_Deprecated_func_finfo_close_0_arg1_str); + attribute_Deprecated_func_finfo_close_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); } static zend_class_entry *register_class_finfo(void) diff --git a/ext/fileinfo/tests/finfo_buffer_deprecated_context_param.phpt b/ext/fileinfo/tests/finfo_buffer_deprecated_context_param.phpt new file mode 100644 index 00000000000..ef4c736999d --- /dev/null +++ b/ext/fileinfo/tests/finfo_buffer_deprecated_context_param.phpt @@ -0,0 +1,20 @@ +--TEST-- +finfo_buffer() deprecated $context param +--EXTENSIONS-- +fileinfo +--FILE-- +buffer($buffer, FILEINFO_NONE, null)); + +?> +--EXPECTF-- +Deprecated: finfo_buffer(): The $context parameter has no effect for finfo_buffer() in %s on line %d +string(36) "ASCII text, with no line terminators" + +Deprecated: finfo::buffer(): The $context parameter has no effect for finfo_buffer() in %s on line %d +string(36) "ASCII text, with no line terminators" diff --git a/ext/fileinfo/tests/finfo_close_basic.phpt b/ext/fileinfo/tests/finfo_close_basic.phpt index cdaf4b23b00..1abd7216390 100644 --- a/ext/fileinfo/tests/finfo_close_basic.phpt +++ b/ext/fileinfo/tests/finfo_close_basic.phpt @@ -23,6 +23,8 @@ unset( $finfo ); *** Testing finfo_close() : basic functionality *** object(finfo)#%d (0) { } + +Deprecated: Function finfo_close() is deprecated since 8.5, as finfo objects are freed automatically in %s on line %d bool(true) object(finfo)#%d (%d) { } diff --git a/ext/fileinfo/tests/finfo_close_error.phpt b/ext/fileinfo/tests/finfo_close_error.phpt index c43597f26a4..c7873b46272 100644 --- a/ext/fileinfo/tests/finfo_close_error.phpt +++ b/ext/fileinfo/tests/finfo_close_error.phpt @@ -15,8 +15,10 @@ try { } ?> ---EXPECT-- +--EXPECTF-- *** Testing finfo_close() : error conditions *** -- Testing finfo_close() function with wrong resource type -- + +Deprecated: Function finfo_close() is deprecated since 8.5, as finfo objects are freed automatically in %s on line %d finfo_close(): Argument #1 ($finfo) must be of type finfo, resource given diff --git a/ext/filter/filter_arginfo.h b/ext/filter/filter_arginfo.h index 32a5c87184a..fde47bfc7f1 100644 --- a/ext/filter/filter_arginfo.h +++ b/ext/filter/filter_arginfo.h @@ -119,18 +119,13 @@ static void register_filter_symbols(int module_number) zend_attribute *attribute_Deprecated_const_FILTER_SANITIZE_STRING_0 = zend_add_global_constant_attribute(const_FILTER_SANITIZE_STRING, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_const_FILTER_SANITIZE_STRING_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_1)); attribute_Deprecated_const_FILTER_SANITIZE_STRING_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_const_FILTER_SANITIZE_STRING_0_arg1; zend_string *attribute_Deprecated_const_FILTER_SANITIZE_STRING_0_arg1_str = zend_string_init("use htmlspecialchars() instead", strlen("use htmlspecialchars() instead"), 1); - ZVAL_STR(&attribute_Deprecated_const_FILTER_SANITIZE_STRING_0_arg1, attribute_Deprecated_const_FILTER_SANITIZE_STRING_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_const_FILTER_SANITIZE_STRING_0->args[1].value, &attribute_Deprecated_const_FILTER_SANITIZE_STRING_0_arg1); + ZVAL_STR(&attribute_Deprecated_const_FILTER_SANITIZE_STRING_0->args[1].value, attribute_Deprecated_const_FILTER_SANITIZE_STRING_0_arg1_str); attribute_Deprecated_const_FILTER_SANITIZE_STRING_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_const_FILTER_SANITIZE_STRIPPED_0 = zend_add_global_constant_attribute(const_FILTER_SANITIZE_STRIPPED, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_const_FILTER_SANITIZE_STRIPPED_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_1)); attribute_Deprecated_const_FILTER_SANITIZE_STRIPPED_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_const_FILTER_SANITIZE_STRIPPED_0_arg1; - zend_string *attribute_Deprecated_const_FILTER_SANITIZE_STRIPPED_0_arg1_str = zend_string_init("use htmlspecialchars() instead", strlen("use htmlspecialchars() instead"), 1); - ZVAL_STR(&attribute_Deprecated_const_FILTER_SANITIZE_STRIPPED_0_arg1, attribute_Deprecated_const_FILTER_SANITIZE_STRIPPED_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_const_FILTER_SANITIZE_STRIPPED_0->args[1].value, &attribute_Deprecated_const_FILTER_SANITIZE_STRIPPED_0_arg1); + ZVAL_STR_COPY(&attribute_Deprecated_const_FILTER_SANITIZE_STRIPPED_0->args[1].value, attribute_Deprecated_const_FILTER_SANITIZE_STRING_0_arg1_str); attribute_Deprecated_const_FILTER_SANITIZE_STRIPPED_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); } diff --git a/ext/ftp/ftp.c b/ext/ftp/ftp.c index f37ee686176..ceb3ee25090 100644 --- a/ext/ftp/ftp.c +++ b/ext/ftp/ftp.c @@ -1382,7 +1382,8 @@ static int my_poll(php_socket_t fd, int events, int timeout) { if (n == -1 && php_socket_errno() == EINTR) { zend_hrtime_t delta_ns = zend_hrtime() - start_ns; - if (delta_ns > timeout_hr) { + /* delta_ns == 0 is only possible with a platform that does not support a high-res timer. */ + if (delta_ns > timeout_hr || UNEXPECTED(delta_ns == 0)) { #ifndef PHP_WIN32 errno = ETIMEDOUT; #endif diff --git a/ext/gd/gd.c b/ext/gd/gd.c index 3c1eac69b96..10e52702952 100644 --- a/ext/gd/gd.c +++ b/ext/gd/gd.c @@ -34,6 +34,7 @@ #include "ext/standard/info.h" #include "php_open_temporary_file.h" #include "php_memory_streams.h" +#include "zend_attributes.h" #include "zend_object_handlers.h" #ifdef HAVE_SYS_WAIT_H @@ -1573,7 +1574,7 @@ static void _php_image_create_from(INTERNAL_FUNCTION_PARAMETERS, int image_type, pefree(pstr, 1); zend_string_release_ex(buff, 0); } - else if (php_stream_can_cast(stream, PHP_STREAM_AS_STDIO)) { + else if (php_stream_can_cast(stream, PHP_STREAM_AS_STDIO) == SUCCESS) { /* try and force the stream to be FILE* */ if (FAILURE == php_stream_cast(stream, PHP_STREAM_AS_STDIO | PHP_STREAM_CAST_TRY_HARD, (void **) &fp, REPORT_ERRORS)) { goto out_err; diff --git a/ext/gd/gd.stub.php b/ext/gd/gd.stub.php index d63c5ea7725..277dd7afeba 100644 --- a/ext/gd/gd.stub.php +++ b/ext/gd/gd.stub.php @@ -629,6 +629,7 @@ function imagegd2(GdImage $image, ?string $file = null, int $chunk_size = 128, i /** @param resource|string|null $file */ function imagebmp(GdImage $image, $file = null, bool $compressed = true): bool {} +#[\Deprecated(since: '8.5', message: "as it has no effect since PHP 8.0")] function imagedestroy(GdImage $image): true {} function imagecolorallocate(GdImage $image, int $red, int $green, int $blue): int|false {} diff --git a/ext/gd/gd_arginfo.h b/ext/gd/gd_arginfo.h index d46c9f06f6e..3332fb70bbc 100644 --- a/ext/gd/gd_arginfo.h +++ b/ext/gd/gd_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 3db75a07cd5dfda50f239bc8c3992cd6d1e7afcb */ + * Stub hash: bbf4c8d4a3ee5712120bd89f4a2ecc516ea65ff1 */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_gd_info, 0, 0, IS_ARRAY, 0) ZEND_END_ARG_INFO() @@ -759,7 +759,7 @@ static const zend_function_entry ext_functions[] = { ZEND_FE(imagegd, arginfo_imagegd) ZEND_FE(imagegd2, arginfo_imagegd2) ZEND_FE(imagebmp, arginfo_imagebmp) - ZEND_FE(imagedestroy, arginfo_imagedestroy) + ZEND_RAW_FENTRY("imagedestroy", zif_imagedestroy, arginfo_imagedestroy, ZEND_ACC_DEPRECATED, NULL, NULL) ZEND_FE(imagecolorallocate, arginfo_imagecolorallocate) ZEND_FE(imagepalettecopy, arginfo_imagepalettecopy) ZEND_FE(imagecolorat, arginfo_imagecolorat) @@ -923,6 +923,14 @@ static void register_gd_symbols(int module_number) REGISTER_LONG_CONSTANT("PNG_FILTER_PAETH", 0x80, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("PNG_ALL_FILTERS", 0x8 | 0x10 | 0x20 | 0x40 | 0x80, CONST_PERSISTENT); #endif + + + zend_attribute *attribute_Deprecated_func_imagedestroy_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "imagedestroy", sizeof("imagedestroy") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + ZVAL_STR(&attribute_Deprecated_func_imagedestroy_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_5)); + attribute_Deprecated_func_imagedestroy_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zend_string *attribute_Deprecated_func_imagedestroy_0_arg1_str = zend_string_init("as it has no effect since PHP 8.0", strlen("as it has no effect since PHP 8.0"), 1); + ZVAL_STR(&attribute_Deprecated_func_imagedestroy_0->args[1].value, attribute_Deprecated_func_imagedestroy_0_arg1_str); + attribute_Deprecated_func_imagedestroy_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); } static zend_class_entry *register_class_GdImage(void) diff --git a/ext/gd/tests/bug19366.phpt b/ext/gd/tests/bug19366.phpt index 7fae0be5d7e..93288dc96ad 100644 --- a/ext/gd/tests/bug19366.phpt +++ b/ext/gd/tests/bug19366.phpt @@ -36,8 +36,6 @@ echo "Alive: Send to browser\n"; //Header("Content-type: image/PNG"); //ImagePNG($ImHandle); -echo "Alive: Free resources\n"; -imagedestroy($ImHandle); echo "Alive: Done\n"; ?> --EXPECT-- @@ -46,5 +44,4 @@ Alive: Define colors Alive: Draw Alive: ImageString Alive: Send to browser -Alive: Free resources Alive: Done diff --git a/ext/gd/tests/bug28147.phpt b/ext/gd/tests/bug28147.phpt index 90314b15322..0578f659bd9 100644 --- a/ext/gd/tests/bug28147.phpt +++ b/ext/gd/tests/bug28147.phpt @@ -16,8 +16,6 @@ imagefilledrectangle($im,0,0,299,299,$w); imageantialias($im,true); imageline($im, 299, 299, 0, 299, $red); -imagedestroy($im); - echo "Alive\n"; ?> --EXPECT-- diff --git a/ext/gd/tests/bug36697-mb.phpt b/ext/gd/tests/bug36697-mb.phpt index 0a661012bcb..f061076da72 100644 --- a/ext/gd/tests/bug36697-mb.phpt +++ b/ext/gd/tests/bug36697-mb.phpt @@ -13,7 +13,7 @@ imagecolortransparent($im, $trans_color); imagefilledrectangle($im, 0,0, 192,36, $trans_color); $c = imagecolorat($im, 191,35); imagegif($im, $dest); -imagedestroy($im); +$im = null; $im = imagecreatefromgif($dest); $c = imagecolorat($im, 191, 35); $colors = imagecolorsforindex($im, $c); diff --git a/ext/gd/tests/bug36697.phpt b/ext/gd/tests/bug36697.phpt index ae6cc5bc64d..838750ccf25 100644 --- a/ext/gd/tests/bug36697.phpt +++ b/ext/gd/tests/bug36697.phpt @@ -13,7 +13,7 @@ imagecolortransparent($im, $trans_color); imagefilledrectangle($im, 0,0, 192,36, $trans_color); $c = imagecolorat($im, 191,35); imagegif($im, $dest); -imagedestroy($im); +$im = null; $im = imagecreatefromgif($dest); $c = imagecolorat($im, 191, 35); $colors = imagecolorsforindex($im, $c); diff --git a/ext/gd/tests/bug38179.phpt b/ext/gd/tests/bug38179.phpt index 17e9ed28406..1dee6687677 100644 --- a/ext/gd/tests/bug38179.phpt +++ b/ext/gd/tests/bug38179.phpt @@ -18,8 +18,6 @@ imagecopy($dst_tc, $src, 0,0, 0,0, imagesx($src), imagesy($src)); $p1 = imagecolorat($dst_tc, 3,3); printf("%X\n", $p1); - -imagedestroy($src); imagedestroy($dst_tc); ?> --EXPECT-- 46FF0000 diff --git a/ext/gd/tests/bug42434.phpt b/ext/gd/tests/bug42434.phpt index d7cca5ab6b3..ddc6c8000d6 100644 --- a/ext/gd/tests/bug42434.phpt +++ b/ext/gd/tests/bug42434.phpt @@ -15,8 +15,6 @@ if (imagecolorat($im, 9, 0) == 0x000000) { } else { echo 'Bugged'; } - -imagedestroy($im); ?> --EXPECT-- DONE diff --git a/ext/gd/tests/bug43121.phpt b/ext/gd/tests/bug43121.phpt index 21550a03c88..81eb564a5e6 100644 --- a/ext/gd/tests/bug43121.phpt +++ b/ext/gd/tests/bug43121.phpt @@ -17,8 +17,6 @@ $im_tile = ImageCreateFromGif(__DIR__ . "/bug43121.gif" ); ImageSetTile( $im, $im_tile ); ImageFill( $im, 0, 0, IMG_COLOR_TILED ); -ImageDestroy( $im ); - print "OK"; ?> --EXPECT-- diff --git a/ext/gd/tests/bug43828.phpt b/ext/gd/tests/bug43828.phpt index 8bc3f9bbcaf..fd6620666f8 100644 --- a/ext/gd/tests/bug43828.phpt +++ b/ext/gd/tests/bug43828.phpt @@ -23,8 +23,6 @@ imagefilledarc($im, 49, 49, 99,99, 0 , 360, $color, IMG_ARC_PIE); include_once __DIR__ . '/func.inc'; test_image_equals_file(__DIR__ . '/bug43828.png', $im); - -imagedestroy($im); ?> --EXPECT-- The images are equal. diff --git a/ext/gd/tests/bug45799.phpt b/ext/gd/tests/bug45799.phpt index f7124ce5b97..dc20efdbb94 100644 --- a/ext/gd/tests/bug45799.phpt +++ b/ext/gd/tests/bug45799.phpt @@ -12,7 +12,6 @@ if (!(imagetypes() & IMG_PNG)) { --EXPECTF-- Warning: imagepng(): gd-png error: no colors in palette%win %s on line %d diff --git a/ext/gd/tests/bug50194.phpt b/ext/gd/tests/bug50194.phpt index 33d2400c46e..860ac3d5053 100644 --- a/ext/gd/tests/bug50194.phpt +++ b/ext/gd/tests/bug50194.phpt @@ -32,8 +32,6 @@ if (isset($matches[1]) && $matches[1] > 2000) { } else { echo "The images are similar.\n"; } - -imagedestroy($im); ?> --EXPECT-- The images are similar. diff --git a/ext/gd/tests/bug61221.phpt b/ext/gd/tests/bug61221.phpt index 97a90db045b..fa2d89cff34 100644 --- a/ext/gd/tests/bug61221.phpt +++ b/ext/gd/tests/bug61221.phpt @@ -15,7 +15,6 @@ imageline($img, 0, $imageh / 2, $imagew - 1, $imageh / 2, $redsolid); imagegammacorrect($img, 1, 1); $color = imagecolorat($img, 0, 0); var_dump($color === $blacktransparent); -imagedestroy($img); ?> --EXPECT-- bool(true) diff --git a/ext/gd/tests/bug65148.phpt b/ext/gd/tests/bug65148.phpt index 4dfa13ccaa9..0d71655aad1 100644 --- a/ext/gd/tests/bug65148.phpt +++ b/ext/gd/tests/bug65148.phpt @@ -37,10 +37,8 @@ foreach ($interpolations as $name => $interpolation) { $t = imagecolorallocatealpha($img, 0, 0, 0, 127); $imgr = imagerotate($img, -5, $t); $results[$name] = array('x' => imagesx($imgr), 'y' => imagesy($imgr)); - imagedestroy($imgr); } -imagedestroy($img); print_r($results); ?> --EXPECT-- diff --git a/ext/gd/tests/bug67325.phpt b/ext/gd/tests/bug67325.phpt index b1e84242a4a..fe5602567f8 100644 --- a/ext/gd/tests/bug67325.phpt +++ b/ext/gd/tests/bug67325.phpt @@ -24,8 +24,6 @@ for ($i = 0; $i < 256; $i++) { } } var_dump($white); - -imagedestroy($im); ?> --EXPECT-- int(0) diff --git a/ext/gd/tests/bug67447.phpt b/ext/gd/tests/bug67447.phpt index e78e272ff2e..f8e4d20c794 100644 --- a/ext/gd/tests/bug67447.phpt +++ b/ext/gd/tests/bug67447.phpt @@ -10,8 +10,6 @@ $red = imagecolorallocate($image, 255, 0, 0); imagefill($image, 0, 0, $red); $cropped = imagecrop($image, ['x' => 0, 'y' => 0, 'width' => 250, 'height' => 250]); var_dump(imagecolorat($cropped, 249, 249) === $red); -imagedestroy($image); -imagedestroy($cropped); // palette $image = imagecreate(500, 500); @@ -20,8 +18,6 @@ $red = imagecolorallocate($image, 255, 0, 0); imagefill($image, 0, 0, $red); $cropped = imagecrop($image, ['x' => 0, 'y' => 0, 'width' => 250, 'height' => 250]); var_dump(imagecolorsforindex($cropped, imagecolorat($cropped, 249, 249))); -imagedestroy($image); -imagedestroy($cropped); ?> --EXPECT-- bool(true) diff --git a/ext/gd/tests/bug69024.phpt b/ext/gd/tests/bug69024.phpt index da80a5b609a..d6eaa40a31f 100644 --- a/ext/gd/tests/bug69024.phpt +++ b/ext/gd/tests/bug69024.phpt @@ -6,7 +6,6 @@ gd --EXPECT-- diff --git a/ext/gd/tests/bug70102.phpt b/ext/gd/tests/bug70102.phpt index bfdcbd377a3..63a81f7cc46 100644 --- a/ext/gd/tests/bug70102.phpt +++ b/ext/gd/tests/bug70102.phpt @@ -19,7 +19,6 @@ $white = imagecolorallocate($im, 255, 255, 255); var_dump($white & 0xffffff); imagefilledrectangle($im, 0, 0, 7, 7, $white); imagewebp($im, $filename); -imagedestroy($im); $im = imagecreatefromwebp($filename); $color = imagecolorat($im, 4, 4); diff --git a/ext/gd/tests/bug72339.phpt b/ext/gd/tests/bug72339.phpt index 561a1b347b5..c6c30c50207 100644 --- a/ext/gd/tests/bug72339.phpt +++ b/ext/gd/tests/bug72339.phpt @@ -33,9 +33,6 @@ fclose($fh); $im = imagecreatefromgd2($fname); -if ($im) { - imagedestroy($im); -} unlink($fname); ?> diff --git a/ext/gd/tests/bug72709.phpt b/ext/gd/tests/bug72709.phpt index b0b4aa77bdf..bc20d1bf58b 100644 --- a/ext/gd/tests/bug72709.phpt +++ b/ext/gd/tests/bug72709.phpt @@ -14,7 +14,6 @@ catch (\Error $ex) { } imagesetpixel($im, 0, 0, IMG_COLOR_STYLED); -imagedestroy($im); ?> ====DONE==== --EXPECT-- diff --git a/ext/gd/tests/bug77198_auto.phpt b/ext/gd/tests/bug77198_auto.phpt index 9df67d7f2ff..5153ec4870a 100644 --- a/ext/gd/tests/bug77198_auto.phpt +++ b/ext/gd/tests/bug77198_auto.phpt @@ -39,9 +39,7 @@ for ($y = 0; $y < 8; $y++) { if ($color !== 0x000000) { printf("Pixel at %d, %d: unexpected color (%d)\n", $x, $y, $color); } - imagedestroy($cropped); } - imagedestroy($orig); } } diff --git a/ext/gd/tests/bug77198_threshold.phpt b/ext/gd/tests/bug77198_threshold.phpt index e164286afca..662ebbe75c0 100644 --- a/ext/gd/tests/bug77198_threshold.phpt +++ b/ext/gd/tests/bug77198_threshold.phpt @@ -36,9 +36,7 @@ for ($y = 0; $y < 8; $y++) { if ($color !== 0x000000) { printf("Pixel at %d, %d: unexpected color (%d)\n", $x, $y, $color); } - imagedestroy($cropped); } - imagedestroy($orig); } } diff --git a/ext/gd/tests/colorat.phpt b/ext/gd/tests/colorat.phpt index d0e62aca910..82d6d56b5c7 100644 --- a/ext/gd/tests/colorat.phpt +++ b/ext/gd/tests/colorat.phpt @@ -15,7 +15,6 @@ echo 'test colorat truecolor: '; $c = imagecolorat($im, 3,3); echo $c == 0x0 ? 'ok' : 'failed'; echo "\n"; -imagedestroy($im); $im = imagecreate(6,6); $c1 = imagecolorallocate($im, 255,255,255); diff --git a/ext/gd/tests/colorclosest.phpt b/ext/gd/tests/colorclosest.phpt index 2633b24017d..8cfcbdcdea4 100644 --- a/ext/gd/tests/colorclosest.phpt +++ b/ext/gd/tests/colorclosest.phpt @@ -8,7 +8,7 @@ gd $im = imagecreatetruecolor(5,5); $c = imagecolorclosest($im, 255,0,255); printf("%X\n", $c); -imagedestroy($im); +$im = null; $im = imagecreate(5,5); $c = imagecolorclosest($im, 255,0,255); @@ -17,13 +17,13 @@ try { } catch (ValueError $exception) { echo $exception->getMessage() . "\n"; } -imagedestroy($im); +$im = null; $im = imagecreate(5,5); imagecolorallocate($im, 255, 0, 255); $c = imagecolorclosest($im, 255,0,255); print_r(imagecolorsforindex($im, $c)); -imagedestroy($im); +$im = null; $im = imagecreate(5,5); for ($i=0; $i<255; $i++) imagecolorresolve($im, $i,0,0); @@ -46,7 +46,7 @@ print_r(imagecolorsforindex($im, $c)); $im = imagecreatetruecolor(5,5); $c = imagecolorclosestalpha($im, 255,0,255,100); printf("%X\n", $c); -imagedestroy($im); +$im = null; $im = imagecreate(5,5); $c = imagecolorclosestalpha($im, 255,0,255,100); @@ -55,13 +55,13 @@ try { } catch (ValueError $exception) { echo $exception->getMessage() . "\n"; } -imagedestroy($im); +$im = null; $im = imagecreate(5,5); imagecolorallocatealpha($im, 255, 0, 255, 1); $c = imagecolorclosestalpha($im, 255,0,255,1); print_r(imagecolorsforindex($im, $c)); -imagedestroy($im); +$im = null; $im = imagecreate(5,5); for ($i=0; $i<255; $i++) imagecolorresolvealpha($im, $i,0,0,1); diff --git a/ext/gd/tests/colorexact.phpt b/ext/gd/tests/colorexact.phpt index 361701c77d3..c28ad54d501 100644 --- a/ext/gd/tests/colorexact.phpt +++ b/ext/gd/tests/colorexact.phpt @@ -12,7 +12,7 @@ $c2 = imagecolorexactalpha($im, 255,0,255, 100); printf("%X\n", $c); printf("%X\n", $c2); -imagedestroy($im); +$im = null; $im = imagecreate(5,5); $c = imagecolorallocate($im, 255,0,255); @@ -26,8 +26,6 @@ echo imagecolorexactalpha($im, 255,200,0,100) . "\n"; // unallocated index echo imagecolorexact($im, 12,12,12) . "\n"; - -imagedestroy($im); ?> --EXPECT-- FF00FF diff --git a/ext/gd/tests/colormatch.phpt b/ext/gd/tests/colormatch.phpt index 65b690ecd01..fe22784c994 100644 --- a/ext/gd/tests/colormatch.phpt +++ b/ext/gd/tests/colormatch.phpt @@ -15,8 +15,6 @@ try { } echo "ok\n"; - -imagedestroy($im); ?> --EXPECT-- imagecolormatch(): Argument #2 ($image2) must have at least one color diff --git a/ext/gd/tests/colorresolve.phpt b/ext/gd/tests/colorresolve.phpt index 08daa4bb5f0..595018e73dc 100644 --- a/ext/gd/tests/colorresolve.phpt +++ b/ext/gd/tests/colorresolve.phpt @@ -8,12 +8,12 @@ gd $im = imagecreatetruecolor(5,5); $c = imagecolorresolve($im, 255,0,255); printf("%X\n", $c); -imagedestroy($im); +$im = null; $im = imagecreate(5,5); $c = imagecolorresolve($im, 255,0,255); print_r(imagecolorsforindex($im, $c)); -imagedestroy($im); +$im = null; $im = imagecreate(5,5); for ($i=0; $i<255; $i++) imagecolorresolve($im, $i,0,0); @@ -38,12 +38,12 @@ print_r(imagecolorsforindex($im, $c)); $im = imagecreatetruecolor(5,5); $c = imagecolorresolvealpha($im, 255,0,255, 100); printf("%X\n", $c); -imagedestroy($im); +$im = null; $im = imagecreate(5,5); $c = imagecolorresolvealpha($im, 255,0,255,100); print_r(imagecolorsforindex($im, $c)); -imagedestroy($im); +$im = null; $im = imagecreate(5,5); for ($i=0; $i<255; $i++) imagecolorresolvealpha($im, $i,0,0,1); diff --git a/ext/gd/tests/copy.phpt b/ext/gd/tests/copy.phpt index 5f099090e66..dc0b5ca1293 100644 --- a/ext/gd/tests/copy.phpt +++ b/ext/gd/tests/copy.phpt @@ -22,7 +22,8 @@ if ($p1 && $p2 && $p3) { echo "TC/TC: ok\n"; } -imagedestroy($src_tc); imagedestroy($dst_tc); +$src_tc = null; +$dst_tc = null; $src_tc = imagecreatetruecolor(5,5); @@ -46,7 +47,8 @@ $p3 = $c3['red'] == 0x00 && $c3['blue']==0x00 && $c3['green']==0xff; if ($p1 && $p2 && $p3) { echo "TC/P: ok\n"; } -imagedestroy($src_tc); imagedestroy($dst_tc); +$src_tc = null; +$dst_tc = null; diff --git a/ext/gd/tests/dashedlines.phpt b/ext/gd/tests/dashedlines.phpt index 11b2e83fad4..552b2bfc297 100644 --- a/ext/gd/tests/dashedlines.phpt +++ b/ext/gd/tests/dashedlines.phpt @@ -26,7 +26,7 @@ $p5 = imagecolorat($im, 5,5) == $b; if ($p1 && $p2 && $p3 && $p4 && $p5) { echo "Horizontal: ok\n"; } -imagedestroy($im); +$im = null; $im = imagecreatetruecolor(6,6); imagefill($im, 0,0, 0xffffff); @@ -46,7 +46,7 @@ $p6 = imagecolorat($im, 2,5) == $b; if ($p1 && $p2 && $p3 && $p4 && $p5 && $p6) { echo "Vertical: ok\n"; } -imagedestroy($im); +$im = null; $im = imagecreatetruecolor(6,6); @@ -66,9 +66,6 @@ $p6 = imagecolorat($im, 5,5) == $b; if ($p1 && $p2 && $p3 && $p4 && $p5 && $p6) { echo "Diagonal: ok\n"; } -imagedestroy($im); - - ?> --EXPECT-- Horizontal: ok diff --git a/ext/gd/tests/gh16232.phpt b/ext/gd/tests/gh16232.phpt index 7f839d737bb..469ae633c5d 100644 --- a/ext/gd/tests/gh16232.phpt +++ b/ext/gd/tests/gh16232.phpt @@ -9,10 +9,10 @@ $bad_webp = __DIR__ . "/gh16232.webp"; copy($good_webp, $bad_webp); var_dump(imagecreatefromwbmp($bad_webp)); $data = file_get_contents($bad_webp); -$data[3] = chr(-1); +$data[3] = chr(255); file_put_contents($bad_webp, $data); var_dump(imagecreatefromwbmp($bad_webp)); -$data[3] = chr(1000); +$data[3] = chr(232); file_put_contents($bad_webp, $data); var_dump(imagecreatefromwbmp($bad_webp)); unlink($bad_webp); diff --git a/ext/gd/tests/imagecolorclosesthwb_basic_001.phpt b/ext/gd/tests/imagecolorclosesthwb_basic_001.phpt index c450ee6f4e4..31982cc64de 100644 --- a/ext/gd/tests/imagecolorclosesthwb_basic_001.phpt +++ b/ext/gd/tests/imagecolorclosesthwb_basic_001.phpt @@ -21,8 +21,6 @@ gd var_dump(imagecolorclosesthwb($image, 0, 24, 200)); // 0 var_dump(imagecolorclosesthwb($image, 116, 120, 115)); // 1 var_dump(imagecolorclosesthwb($image, 50, 0, 90)); // 0 - - imagedestroy($image); ?> --EXPECT-- int(0) diff --git a/ext/gd/tests/imagecolorset_basic.phpt b/ext/gd/tests/imagecolorset_basic.phpt index 7677b85948a..006202007fa 100644 --- a/ext/gd/tests/imagecolorset_basic.phpt +++ b/ext/gd/tests/imagecolorset_basic.phpt @@ -28,7 +28,6 @@ imagecolorset($im, $bg, 0, 0, 255); imagepalettetotruecolor($im); include_once __DIR__ . '/func.inc'; test_image_equals_file(__DIR__ . '/imagecolorset_basic.png', $im); -imagedestroy($im); ?> --EXPECT-- The images are equal. diff --git a/ext/gd/tests/imagecolorstotal_basic.phpt b/ext/gd/tests/imagecolorstotal_basic.phpt index 8f90b05e235..b95275cd324 100644 --- a/ext/gd/tests/imagecolorstotal_basic.phpt +++ b/ext/gd/tests/imagecolorstotal_basic.phpt @@ -17,9 +17,6 @@ $gif = __DIR__."/php.gif"; $im = imagecreatefromgif($gif); echo 'Total colors in image: ' . imagecolorstotal($im); - -// Free image -imagedestroy($im); ?> --EXPECT-- *** Testing imagecolorstotal() : basic functionality *** diff --git a/ext/gd/tests/imagecolourstotal_basic.phpt b/ext/gd/tests/imagecolourstotal_basic.phpt index 0c9fd763247..f66a6842485 100644 --- a/ext/gd/tests/imagecolourstotal_basic.phpt +++ b/ext/gd/tests/imagecolourstotal_basic.phpt @@ -22,15 +22,13 @@ var_dump( imagecolorstotal( $img )); $bg = imagecolorallocate( $img, 255, 0, 0 ); $bg = imagecolorallocate( $img, 0, 0, 255 ); var_dump( imagecolorstotal( $img )); -imagedestroy( $img ); +$img = null; // Truecolor image $img = imagecreatetruecolor( 50, 50 ); var_dump( imagecolorstotal( $img ) ); $bg = imagecolorallocate( $img, 255, 255, 255 ); var_dump( imagecolorstotal( $img ) ); -imagedestroy( $img ); - ?> --EXPECT-- *** Testing imagecolorstotal() : basic functionality *** diff --git a/ext/gd/tests/imagecopyresampled_basic.phpt b/ext/gd/tests/imagecopyresampled_basic.phpt index 9fb1178e540..3f2f7352723 100644 --- a/ext/gd/tests/imagecopyresampled_basic.phpt +++ b/ext/gd/tests/imagecopyresampled_basic.phpt @@ -47,11 +47,6 @@ imagepng($image_sml, $dest_sml); list($width, $height) = getimagesize($dest_sml); echo "Size of copy: width=". $width . " height=" . $height . "\n"; - -imagedestroy($image_lge); -imagedestroy($image_sml); - - echo "Done\n"; ?> --CLEAN-- diff --git a/ext/gd/tests/imagecopyresampled_variation1.phpt b/ext/gd/tests/imagecopyresampled_variation1.phpt index 20734476556..6c3fd021a1a 100644 --- a/ext/gd/tests/imagecopyresampled_variation1.phpt +++ b/ext/gd/tests/imagecopyresampled_variation1.phpt @@ -59,9 +59,6 @@ if (!($alpha >= EXP_ALPHA - 1 && $alpha <= EXP_ALPHA + 1)) { printf("alpha: expected roughly %d, got %d\n", EXP_ALPHA, $alpha); } -imagedestroy($copy); -imagedestroy($im); - echo 'DONE'; ?> --EXPECT-- diff --git a/ext/gd/tests/imagedashedline_basic.phpt b/ext/gd/tests/imagedashedline_basic.phpt index d9ca69ad5f0..f676abd921d 100644 --- a/ext/gd/tests/imagedashedline_basic.phpt +++ b/ext/gd/tests/imagedashedline_basic.phpt @@ -41,7 +41,6 @@ $color1 = imagecolorsforindex($image, $col1); $color2 = imagecolorsforindex($image, $col2); var_dump($color1, $color2); -imagedestroy($image); echo "Done\n"; ?> --CLEAN-- diff --git a/ext/gd/tests/imagedestroy_deprecated.phpt b/ext/gd/tests/imagedestroy_deprecated.phpt new file mode 100644 index 00000000000..37c39fbfe27 --- /dev/null +++ b/ext/gd/tests/imagedestroy_deprecated.phpt @@ -0,0 +1,11 @@ +--TEST-- +imagedestroy() deprecation message +--EXTENSIONS-- +gd +--FILE-- + +--EXPECTF-- +Deprecated: Function imagedestroy() is deprecated since 8.5, as it has no effect since PHP 8.0 in %s on line %d diff --git a/ext/gd/tests/imagefill_1.phpt b/ext/gd/tests/imagefill_1.phpt index d8631f73cc4..113c1c98438 100644 --- a/ext/gd/tests/imagefill_1.phpt +++ b/ext/gd/tests/imagefill_1.phpt @@ -18,7 +18,6 @@ $green = imagecolorallocate($im, 0,255,0); print_r(imagecolorat($im, 0,0)); imagefill($im, 0,0,$white + 3); print_r(imagecolorat($im, 0,0)); -imagedestroy($im); ?> --EXPECT-- 00 diff --git a/ext/gd/tests/imagefilledpolygon_basic.phpt b/ext/gd/tests/imagefilledpolygon_basic.phpt index bbb8f9c2eb0..3681d96c6e7 100644 --- a/ext/gd/tests/imagefilledpolygon_basic.phpt +++ b/ext/gd/tests/imagefilledpolygon_basic.phpt @@ -55,9 +55,6 @@ $color2 = imagecolorsforindex($image_in, $col2); $color3 = imagecolorsforindex($image_in, $col3); var_dump($color1, $color2, $color3); -imagedestroy($image); -imagedestroy($image_in); - echo "Done\n"; ?> --CLEAN-- diff --git a/ext/gd/tests/imagefttext.phpt b/ext/gd/tests/imagefttext.phpt index a60c4d8afba..83243a78e52 100644 --- a/ext/gd/tests/imagefttext.phpt +++ b/ext/gd/tests/imagefttext.phpt @@ -40,11 +40,10 @@ gd $im = imagecreate(256, 256); var_dump(testrun($im, $fontfile_8859)); - imagedestroy($im); + $im = null; $im = imagecreatetruecolor(256, 256); var_dump(testrun($im, $fontfile_8859)); - imagedestroy($im); ?> --EXPECT-- bool(true) diff --git a/ext/gd/tests/imagepalettetotruecolor_basic.phpt b/ext/gd/tests/imagepalettetotruecolor_basic.phpt index e4e4ee89ca1..d886227a15e 100644 --- a/ext/gd/tests/imagepalettetotruecolor_basic.phpt +++ b/ext/gd/tests/imagepalettetotruecolor_basic.phpt @@ -11,7 +11,6 @@ var_dump($im instanceof GdImage); var_dump(imageistruecolor($im)); var_dump(imagepalettetotruecolor($im)); var_dump(imageistruecolor($im)); -imagedestroy($im); ?> --EXPECT-- bool(true) diff --git a/ext/gd/tests/imagepolygon_basic.phpt b/ext/gd/tests/imagepolygon_basic.phpt index c41b0710ef4..741f34c48ab 100644 --- a/ext/gd/tests/imagepolygon_basic.phpt +++ b/ext/gd/tests/imagepolygon_basic.phpt @@ -42,8 +42,6 @@ $color1 = imagecolorsforindex($image, $col1); $color2 = imagecolorsforindex($image, $col2); var_dump($color1, $color2); -imagedestroy($image); - echo "Done\n"; ?> --CLEAN-- diff --git a/ext/gd/tests/imagerotate_overflow.phpt b/ext/gd/tests/imagerotate_overflow.phpt index a7be335ca92..590f4d7152c 100644 --- a/ext/gd/tests/imagerotate_overflow.phpt +++ b/ext/gd/tests/imagerotate_overflow.phpt @@ -11,14 +11,6 @@ $tmp = imagerotate ($im, 5, -9999999); var_dump($tmp); -if ($tmp) { - imagedestroy($tmp); -} - -if ($im) { - imagedestroy($im); -} - ?> --EXPECT-- bool(false) diff --git a/ext/gd/tests/imagettftext_charmap_order.phpt b/ext/gd/tests/imagettftext_charmap_order.phpt index 32d5c9d0d7e..6fe5353e9fc 100644 --- a/ext/gd/tests/imagettftext_charmap_order.phpt +++ b/ext/gd/tests/imagettftext_charmap_order.phpt @@ -61,7 +61,6 @@ if ($black_pixels >= 10) { } else { printf("FAIL %d black pixels\n", $black_pixels); } -imagedestroy($im); ?> --EXPECTF-- SUCCESS %d black pixels diff --git a/ext/gd/tests/libgd00100.phpt b/ext/gd/tests/libgd00100.phpt index 80e24d0ba20..8f9955640b3 100644 --- a/ext/gd/tests/libgd00100.phpt +++ b/ext/gd/tests/libgd00100.phpt @@ -109,8 +109,6 @@ imagefilledpolygon($im, $points, $black); include_once __DIR__ . '/func.inc'; test_image_equals_file(__DIR__ . '/libgd00100.png', $im); - -imagedestroy($im); ?> --EXPECT-- The images are equal. diff --git a/ext/gd/tests/libgd00186.phpt b/ext/gd/tests/libgd00186.phpt index fb9e2985ced..142f1637b2b 100644 --- a/ext/gd/tests/libgd00186.phpt +++ b/ext/gd/tests/libgd00186.phpt @@ -26,8 +26,6 @@ if ($arr['blue'] == 2) { } else { $r = "Failed"; } -imagedestroy($tile); -imagedestroy($im); echo $r; ?> --EXPECT-- diff --git a/ext/gettext/gettext.c b/ext/gettext/gettext.c index 27f0dfa26da..6badea4a176 100644 --- a/ext/gettext/gettext.c +++ b/ext/gettext/gettext.c @@ -194,7 +194,7 @@ PHP_FUNCTION(bindtextdomain) btd_result = bindtextdomain(ZSTR_VAL(domain), NULL); if (btd_result == NULL) { /* POSIX-compliant implementations can return - * NULL if an error occured. On musl you will + * NULL if an error occurred. On musl you will * also get NULL if the domain is not yet * bound, because musl has no default directory * to return in that case. */ diff --git a/ext/hash/config.m4 b/ext/hash/config.m4 index 5248786efb0..2da44c503a6 100644 --- a/ext/hash/config.m4 +++ b/ext/hash/config.m4 @@ -23,8 +23,7 @@ AS_VAR_IF([ac_cv_c_bigendian_php], [yes], [ SHA3_OPT_SRC="$SHA3_DIR/KeccakP-1600-inplace32BI.c" dnl Add -Wno-implicit-fallthrough flag as it happens on 32 bit builds AX_CHECK_COMPILE_FLAG([-Wno-implicit-fallthrough], - [PHP_HASH_CFLAGS="$PHP_HASH_CFLAGS -Wno-implicit-fallthrough"],, - [-Werror]) + [PHP_HASH_CFLAGS="$PHP_HASH_CFLAGS -Wno-implicit-fallthrough"]) ],[ AC_MSG_RESULT([yes]) SHA3_DIR="sha3/generic64lc" diff --git a/ext/hash/hash.c b/ext/hash/hash.c index 13c345de4dd..75e2e241bec 100644 --- a/ext/hash/hash.c +++ b/ext/hash/hash.c @@ -229,20 +229,20 @@ static void one_to_buffer(size_t sz, unsigned char *buf, uint64_t val) { significant bits first. This allows 32-bit and 64-bit architectures to interchange serialized HashContexts. */ -PHP_HASH_API zend_result php_hash_serialize_spec(const php_hashcontext_object *hash, zval *zv, const char *spec) /* {{{ */ +PHP_HASH_API hash_spec_result php_hash_serialize_spec(const php_hashcontext_object *hash, zval *zv, const char *spec) /* {{{ */ { size_t pos = 0, max_alignment = 1; unsigned char *buf = (unsigned char *) hash->context; zval tmp; if (buf == NULL) { - return FAILURE; + return HASH_SPEC_FAILURE; } array_init(zv); while (*spec != '\0' && *spec != '.') { char spec_ch = *spec; size_t sz, count = parse_serialize_spec(&spec, &pos, &sz, &max_alignment); if (pos + count * sz > hash->ops->context_size) { - return FAILURE; + return HASH_SPEC_FAILURE; } if (isupper((unsigned char) spec_ch)) { pos += count * sz; @@ -265,38 +265,33 @@ PHP_HASH_API zend_result php_hash_serialize_spec(const php_hashcontext_object *h } } if (*spec == '.' && align_to(pos, max_alignment) != hash->ops->context_size) { - return FAILURE; + return HASH_SPEC_FAILURE; } - return SUCCESS; + return HASH_SPEC_SUCCESS; } /* }}} */ -/* Unserialize a hash context serialized by `php_hash_serialize_spec` with `spec`. - Returns SUCCESS on success and a negative error code on failure. - Codes: FAILURE (-1) == generic failure - -999 == spec wrong size for context - -1000 - POS == problem at byte offset POS */ - -PHP_HASH_API int php_hash_unserialize_spec(php_hashcontext_object *hash, const zval *zv, const char *spec) /* {{{ */ +/* Unserialize a hash context serialized by `php_hash_serialize_spec` with `spec`. */ +PHP_HASH_API hash_spec_result php_hash_unserialize_spec(php_hashcontext_object *hash, const zval *zv, const char *spec) /* {{{ */ { size_t pos = 0, max_alignment = 1, j = 0; unsigned char *buf = (unsigned char *) hash->context; zval *elt; if (Z_TYPE_P(zv) != IS_ARRAY) { - return FAILURE; + return HASH_SPEC_FAILURE; } while (*spec != '\0' && *spec != '.') { char spec_ch = *spec; size_t sz, count = parse_serialize_spec(&spec, &pos, &sz, &max_alignment); if (pos + count * sz > hash->ops->context_size) { - return -999; + return WRONG_CONTEXT_SIZE; } if (isupper((unsigned char) spec_ch)) { pos += count * sz; } else if (sz == 1 && count > 1) { elt = zend_hash_index_find(Z_ARRVAL_P(zv), j); if (!elt || Z_TYPE_P(elt) != IS_STRING || Z_STRLEN_P(elt) != count) { - return -1000 - pos; + return BYTE_OFFSET_POS_ERROR - pos; } ++j; memcpy(buf + pos, Z_STRVAL_P(elt), count); @@ -306,14 +301,14 @@ PHP_HASH_API int php_hash_unserialize_spec(php_hashcontext_object *hash, const z uint64_t val; elt = zend_hash_index_find(Z_ARRVAL_P(zv), j); if (!elt || Z_TYPE_P(elt) != IS_LONG) { - return -1000 - pos; + return BYTE_OFFSET_POS_ERROR - pos; } ++j; val = (uint32_t) Z_LVAL_P(elt); if (sz == 8) { elt = zend_hash_index_find(Z_ARRVAL_P(zv), j); if (!elt || Z_TYPE_P(elt) != IS_LONG) { - return -1000 - pos; + return BYTE_OFFSET_POS_ERROR - pos; } ++j; val += ((uint64_t) Z_LVAL_P(elt)) << 32; @@ -325,31 +320,32 @@ PHP_HASH_API int php_hash_unserialize_spec(php_hashcontext_object *hash, const z } } if (*spec == '.' && align_to(pos, max_alignment) != hash->ops->context_size) { - return -999; + return WRONG_CONTEXT_SIZE; } - return SUCCESS; + + return HASH_SPEC_SUCCESS; } /* }}} */ -PHP_HASH_API zend_result php_hash_serialize(const php_hashcontext_object *hash, zend_long *magic, zval *zv) /* {{{ */ +PHP_HASH_API hash_spec_result php_hash_serialize(const php_hashcontext_object *hash, zend_long *magic, zval *zv) /* {{{ */ { - if (hash->ops->serialize_spec) { - *magic = PHP_HASH_SERIALIZE_MAGIC_SPEC; - return php_hash_serialize_spec(hash, zv, hash->ops->serialize_spec); - } else { - return FAILURE; - } + if (!hash->ops->serialize_spec) { + return HASH_SPEC_FAILURE; + } + + *magic = PHP_HASH_SERIALIZE_MAGIC_SPEC; + return php_hash_serialize_spec(hash, zv, hash->ops->serialize_spec); } /* }}} */ -PHP_HASH_API int php_hash_unserialize(php_hashcontext_object *hash, zend_long magic, const zval *zv) /* {{{ */ +PHP_HASH_API hash_spec_result php_hash_unserialize(php_hashcontext_object *hash, zend_long magic, const zval *zv) /* {{{ */ { if (hash->ops->serialize_spec && magic == PHP_HASH_SERIALIZE_MAGIC_SPEC) { return php_hash_unserialize_spec(hash, zv, hash->ops->serialize_spec); - } else { - return FAILURE; } + + return HASH_SPEC_FAILURE; } /* }}} */ @@ -411,7 +407,7 @@ static void php_hash_do_hash( php_hash_bin2hex(ZSTR_VAL(hex_digest), (unsigned char *) ZSTR_VAL(digest), ops->digest_size); ZSTR_VAL(hex_digest)[2 * ops->digest_size] = 0; - zend_string_release_ex(digest, 0); + zend_string_efree(digest); RETURN_NEW_STR(hex_digest); } } @@ -542,7 +538,7 @@ static void php_hash_do_hash_hmac( if (n < 0) { efree(context); efree(K); - zend_string_release(digest); + zend_string_efree(digest); RETURN_FALSE; } @@ -568,7 +564,7 @@ static void php_hash_do_hash_hmac( php_hash_bin2hex(ZSTR_VAL(hex_digest), (unsigned char *) ZSTR_VAL(digest), ops->digest_size); ZSTR_VAL(hex_digest)[2 * ops->digest_size] = 0; - zend_string_release_ex(digest, 0); + zend_string_efree(digest); RETURN_NEW_STR(hex_digest); } } @@ -829,7 +825,7 @@ PHP_FUNCTION(hash_final) php_hash_bin2hex(ZSTR_VAL(hex_digest), (unsigned char *) ZSTR_VAL(digest), digest_len); ZSTR_VAL(hex_digest)[2 * digest_len] = 0; - zend_string_release_ex(digest, 0); + zend_string_efree(digest); RETURN_NEW_STR(hex_digest); } } @@ -851,8 +847,6 @@ PHP_FUNCTION(hash_copy) RETVAL_OBJ(Z_OBJ_HANDLER_P(zhash, clone_obj)(Z_OBJ_P(zhash))); if (php_hashcontext_from_object(Z_OBJ_P(return_value))->context == NULL) { - zval_ptr_dtor(return_value); - zend_throw_error(NULL, "Cannot copy hash"); RETURN_THROWS(); } @@ -1477,7 +1471,7 @@ PHP_METHOD(HashContext, __serialize) ZVAL_LONG(&tmp, hash->options); zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &tmp); - if (hash->ops->hash_serialize(hash, &magic, &tmp) != SUCCESS) { + if (hash->ops->hash_serialize(hash, &magic, &tmp) != HASH_SPEC_SUCCESS) { goto serialize_failure; } zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &tmp); @@ -1506,7 +1500,7 @@ PHP_METHOD(HashContext, __unserialize) HashTable *data; zval *algo_zv, *magic_zv, *options_zv, *hash_zv, *members_zv; zend_long magic, options; - int unserialize_result; + hash_spec_result unserialize_result; const php_hash_ops *ops; if (zend_parse_parameters(ZEND_NUM_ARGS(), "h", &data) == FAILURE) { @@ -1555,7 +1549,7 @@ PHP_METHOD(HashContext, __unserialize) ops->hash_init(hash->context, NULL); unserialize_result = ops->hash_unserialize(hash, magic, hash_zv); - if (unserialize_result != SUCCESS) { + if (unserialize_result != HASH_SPEC_SUCCESS) { zend_throw_exception_ex(NULL, 0, "Incomplete or ill-formed serialization data (\"%s\" code %d)", ops->algo, unserialize_result); /* free context */ php_hashcontext_dtor(Z_OBJ_P(object)); diff --git a/ext/hash/hash_gost.c b/ext/hash/hash_gost.c index 2ad6948a9a6..bba585a11f9 100644 --- a/ext/hash/hash_gost.c +++ b/ext/hash/hash_gost.c @@ -304,17 +304,17 @@ PHP_HASH_API void PHP_GOSTFinal(unsigned char digest[32], PHP_GOST_CTX *context) ZEND_SECURE_ZERO(context, sizeof(*context)); } -static int php_gost_unserialize(php_hashcontext_object *hash, zend_long magic, const zval *zv) +static hash_spec_result php_gost_unserialize(php_hashcontext_object *hash, zend_long magic, const zval *zv) { PHP_GOST_CTX *ctx = (PHP_GOST_CTX *) hash->context; - int r = FAILURE; + hash_spec_result r = HASH_SPEC_FAILURE; if (magic == PHP_HASH_SERIALIZE_MAGIC_SPEC - && (r = php_hash_unserialize_spec(hash, zv, PHP_GOST_SPEC)) == SUCCESS + && (r = php_hash_unserialize_spec(hash, zv, PHP_GOST_SPEC)) == HASH_SPEC_SUCCESS && ctx->length < sizeof(ctx->buffer)) { - return SUCCESS; - } else { - return r != SUCCESS ? r : -2000; + return HASH_SPEC_SUCCESS; } + + return r != HASH_SPEC_SUCCESS ? r : CONTEXT_VALIDATION_FAILURE; } const php_hash_ops php_hash_gost_ops = { diff --git a/ext/hash/hash_md.c b/ext/hash/hash_md.c index 96da7fce82a..dd299e69589 100644 --- a/ext/hash/hash_md.c +++ b/ext/hash/hash_md.c @@ -47,7 +47,7 @@ const php_hash_ops php_hash_md4_ops = { 1 }; -static int php_md2_unserialize(php_hashcontext_object *hash, zend_long magic, const zval *zv); +static hash_spec_result php_md2_unserialize(php_hashcontext_object *hash, zend_long magic, const zval *zv); const php_hash_ops php_hash_md2_ops = { "md2", @@ -356,15 +356,15 @@ PHP_HASH_API void PHP_MD2Final(unsigned char output[16], PHP_MD2_CTX *context) memcpy(output, context->state, 16); } -static int php_md2_unserialize(php_hashcontext_object *hash, zend_long magic, const zval *zv) +static hash_spec_result php_md2_unserialize(php_hashcontext_object *hash, zend_long magic, const zval *zv) { PHP_MD2_CTX *ctx = (PHP_MD2_CTX *) hash->context; - int r = FAILURE; + hash_spec_result r = HASH_SPEC_FAILURE; if (magic == PHP_HASH_SERIALIZE_MAGIC_SPEC - && (r = php_hash_unserialize_spec(hash, zv, PHP_MD2_SPEC)) == SUCCESS + && (r = php_hash_unserialize_spec(hash, zv, PHP_MD2_SPEC)) == HASH_SPEC_SUCCESS && (unsigned char) ctx->in_buffer < sizeof(ctx->buffer)) { - return SUCCESS; - } else { - return r != SUCCESS ? r : -2000; + return HASH_SPEC_SUCCESS; } + + return r != HASH_SPEC_SUCCESS ? r : CONTEXT_VALIDATION_FAILURE; } diff --git a/ext/hash/hash_sha3.c b/ext/hash/hash_sha3.c index 07da2cfd2d0..8fa0a4b4e52 100644 --- a/ext/hash/hash_sha3.c +++ b/ext/hash/hash_sha3.c @@ -200,20 +200,20 @@ static void PHP_SHA3_Final(unsigned char* digest, ZEND_SECURE_ZERO(ctx, sizeof(PHP_SHA3_CTX)); } -static int php_sha3_unserialize(php_hashcontext_object *hash, +static hash_spec_result php_sha3_unserialize(php_hashcontext_object *hash, zend_long magic, const zval *zv, size_t block_size) { PHP_SHA3_CTX *ctx = (PHP_SHA3_CTX *) hash->context; - int r = FAILURE; + hash_spec_result r = HASH_SPEC_FAILURE; if (magic == PHP_HASH_SERIALIZE_MAGIC_SPEC - && (r = php_hash_unserialize_spec(hash, zv, PHP_SHA3_SPEC)) == SUCCESS + && (r = php_hash_unserialize_spec(hash, zv, PHP_SHA3_SPEC)) == HASH_SPEC_SUCCESS && ctx->pos < block_size) { - return SUCCESS; - } else { - return r != SUCCESS ? r : -2000; + return HASH_SPEC_SUCCESS; } + + return r != HASH_SPEC_SUCCESS ? r : CONTEXT_VALIDATION_FAILURE; } // ========================================================================== @@ -292,23 +292,23 @@ const php_hash_ops php_hash_sha3_##bits##_ops = { \ #endif #define PHP_KECCAK_SPEC "b200IiIIB" -static zend_result php_keccak_serialize(const php_hashcontext_object *hash, zend_long *magic, zval *zv) +static hash_spec_result php_keccak_serialize(const php_hashcontext_object *hash, zend_long *magic, zval *zv) { *magic = PHP_HASH_SERIALIZE_MAGIC_KECCAK; return php_hash_serialize_spec(hash, zv, PHP_KECCAK_SPEC); } -static int php_keccak_unserialize(php_hashcontext_object *hash, zend_long magic, const zval *zv) +static hash_spec_result php_keccak_unserialize(php_hashcontext_object *hash, zend_long magic, const zval *zv) { Keccak_HashInstance *ctx = (Keccak_HashInstance *) hash->context; - int r = FAILURE; + hash_spec_result r = HASH_SPEC_FAILURE; if (magic == PHP_HASH_SERIALIZE_MAGIC_KECCAK - && (r = php_hash_unserialize_spec(hash, zv, PHP_KECCAK_SPEC)) == SUCCESS + && (r = php_hash_unserialize_spec(hash, zv, PHP_KECCAK_SPEC)) == HASH_SPEC_SUCCESS && ctx->sponge.byteIOIndex < ctx->sponge.rate / 8) { - return SUCCESS; - } else { - return r != SUCCESS ? r : -2000; + return HASH_SPEC_SUCCESS; } + + return r != HASH_SPEC_SUCCESS ? r : CONTEXT_VALIDATION_FAILURE; } // ========================================================================== diff --git a/ext/hash/hash_snefru.c b/ext/hash/hash_snefru.c index c1dbc3ae57a..b9b70f36420 100644 --- a/ext/hash/hash_snefru.c +++ b/ext/hash/hash_snefru.c @@ -189,17 +189,17 @@ PHP_HASH_API void PHP_SNEFRUFinal(unsigned char digest[32], PHP_SNEFRU_CTX *cont ZEND_SECURE_ZERO(context, sizeof(*context)); } -static int php_snefru_unserialize(php_hashcontext_object *hash, zend_long magic, const zval *zv) +static hash_spec_result php_snefru_unserialize(php_hashcontext_object *hash, zend_long magic, const zval *zv) { PHP_SNEFRU_CTX *ctx = (PHP_SNEFRU_CTX *) hash->context; - int r = FAILURE; + hash_spec_result r = HASH_SPEC_FAILURE; if (magic == PHP_HASH_SERIALIZE_MAGIC_SPEC - && (r = php_hash_unserialize_spec(hash, zv, PHP_SNEFRU_SPEC)) == SUCCESS + && (r = php_hash_unserialize_spec(hash, zv, PHP_SNEFRU_SPEC)) == HASH_SPEC_SUCCESS && ctx->length < sizeof(ctx->buffer)) { - return SUCCESS; - } else { - return r != SUCCESS ? r : -2000; + return HASH_SPEC_SUCCESS; } + + return r != HASH_SPEC_SUCCESS ? r : CONTEXT_VALIDATION_FAILURE; } const php_hash_ops php_hash_snefru_ops = { diff --git a/ext/hash/hash_tiger.c b/ext/hash/hash_tiger.c index 841693a67dd..62d1b734714 100644 --- a/ext/hash/hash_tiger.c +++ b/ext/hash/hash_tiger.c @@ -239,17 +239,17 @@ PHP_HASH_API void PHP_TIGER192Final(unsigned char digest[24], PHP_TIGER_CTX *con ZEND_SECURE_ZERO(context, sizeof(*context)); } -static int php_tiger_unserialize(php_hashcontext_object *hash, zend_long magic, const zval *zv) +static hash_spec_result php_tiger_unserialize(php_hashcontext_object *hash, zend_long magic, const zval *zv) { PHP_TIGER_CTX *ctx = (PHP_TIGER_CTX *) hash->context; - int r = FAILURE; + hash_spec_result r = HASH_SPEC_FAILURE; if (magic == PHP_HASH_SERIALIZE_MAGIC_SPEC - && (r = php_hash_unserialize_spec(hash, zv, PHP_TIGER_SPEC)) == SUCCESS + && (r = php_hash_unserialize_spec(hash, zv, PHP_TIGER_SPEC)) == HASH_SPEC_SUCCESS && ctx->length < sizeof(ctx->buffer)) { - return SUCCESS; - } else { - return r != SUCCESS ? r : -2000; + return HASH_SPEC_SUCCESS; } + + return r != HASH_SPEC_SUCCESS ? r : CONTEXT_VALIDATION_FAILURE; } #define PHP_HASH_TIGER_OPS(p, b) \ diff --git a/ext/hash/hash_whirlpool.c b/ext/hash/hash_whirlpool.c index db5a0da1236..fa3c216a64c 100644 --- a/ext/hash/hash_whirlpool.c +++ b/ext/hash/hash_whirlpool.c @@ -429,20 +429,20 @@ PHP_HASH_API void PHP_WHIRLPOOLFinal(unsigned char digest[64], PHP_WHIRLPOOL_CTX ZEND_SECURE_ZERO(context, sizeof(*context)); } -static int php_whirlpool_unserialize(php_hashcontext_object *hash, zend_long magic, const zval *zv) +static hash_spec_result php_whirlpool_unserialize(php_hashcontext_object *hash, zend_long magic, const zval *zv) { PHP_WHIRLPOOL_CTX *ctx = (PHP_WHIRLPOOL_CTX *) hash->context; - int r = FAILURE; + hash_spec_result r = HASH_SPEC_FAILURE; if (magic == PHP_HASH_SERIALIZE_MAGIC_SPEC - && (r = php_hash_unserialize_spec(hash, zv, PHP_WHIRLPOOL_SPEC)) == SUCCESS + && (r = php_hash_unserialize_spec(hash, zv, PHP_WHIRLPOOL_SPEC)) == HASH_SPEC_SUCCESS && ctx->buffer.pos >= 0 && ctx->buffer.pos < (int) sizeof(ctx->buffer.data) && ctx->buffer.bits >= ctx->buffer.pos * 8 && ctx->buffer.bits < ctx->buffer.pos * 8 + 8) { - return SUCCESS; - } else { - return r != SUCCESS ? r : -2000; + return HASH_SPEC_SUCCESS; } + + return r != HASH_SPEC_SUCCESS ? r : CONTEXT_VALIDATION_FAILURE; } const php_hash_ops php_hash_whirlpool_ops = { diff --git a/ext/hash/hash_xxhash.c b/ext/hash/hash_xxhash.c index 1c1315afd4b..add922e8e84 100644 --- a/ext/hash/hash_xxhash.c +++ b/ext/hash/hash_xxhash.c @@ -17,9 +17,9 @@ #include "php_hash.h" #include "php_hash_xxhash.h" -static int php_hash_xxh32_unserialize( +static hash_spec_result php_hash_xxh32_unserialize( php_hashcontext_object *hash, zend_long magic, const zval *zv); -static int php_hash_xxh64_unserialize( +static hash_spec_result php_hash_xxh64_unserialize( php_hashcontext_object *hash, zend_long magic, const zval *zv); const php_hash_ops php_hash_xxh32_ops = { @@ -75,18 +75,18 @@ PHP_HASH_API zend_result PHP_XXH32Copy(const php_hash_ops *ops, const PHP_XXH32_ return SUCCESS; } -static int php_hash_xxh32_unserialize( +static hash_spec_result php_hash_xxh32_unserialize( php_hashcontext_object *hash, zend_long magic, const zval *zv) { PHP_XXH32_CTX *ctx = (PHP_XXH32_CTX *) hash->context; - int r = FAILURE; + hash_spec_result r = HASH_SPEC_FAILURE; if (magic == PHP_HASH_SERIALIZE_MAGIC_SPEC - && (r = php_hash_unserialize_spec(hash, zv, PHP_XXH32_SPEC)) == SUCCESS + && (r = php_hash_unserialize_spec(hash, zv, PHP_XXH32_SPEC)) == HASH_SPEC_SUCCESS && ctx->s.memsize < 16) { - return SUCCESS; - } else { - return r != SUCCESS ? r : -2000; + return HASH_SPEC_SUCCESS; } + + return r != HASH_SPEC_SUCCESS ? r : CONTEXT_VALIDATION_FAILURE; } const php_hash_ops php_hash_xxh64_ops = { @@ -231,18 +231,18 @@ PHP_HASH_API zend_result PHP_XXH3_64_Copy(const php_hash_ops *ops, const PHP_XXH return SUCCESS; } -static int php_hash_xxh64_unserialize( +static hash_spec_result php_hash_xxh64_unserialize( php_hashcontext_object *hash, zend_long magic, const zval *zv) { PHP_XXH64_CTX *ctx = (PHP_XXH64_CTX *) hash->context; - int r = FAILURE; + hash_spec_result r = HASH_SPEC_FAILURE; if (magic == PHP_HASH_SERIALIZE_MAGIC_SPEC - && (r = php_hash_unserialize_spec(hash, zv, PHP_XXH64_SPEC)) == SUCCESS + && (r = php_hash_unserialize_spec(hash, zv, PHP_XXH64_SPEC)) == HASH_SPEC_SUCCESS && ctx->s.memsize < 32) { - return SUCCESS; - } else { - return r != SUCCESS ? r : -2000; + return HASH_SPEC_SUCCESS; } + + return r != HASH_SPEC_SUCCESS ? r : CONTEXT_VALIDATION_FAILURE; } const php_hash_ops php_hash_xxh3_128_ops = { diff --git a/ext/hash/php_hash.h b/ext/hash/php_hash.h index 3b058ef48bd..f56605a33be 100644 --- a/ext/hash/php_hash.h +++ b/ext/hash/php_hash.h @@ -29,14 +29,22 @@ #define L64 INT64_C +typedef enum { + HASH_SPEC_SUCCESS = 0, + HASH_SPEC_FAILURE = -1, + WRONG_CONTEXT_SIZE = -999, + BYTE_OFFSET_POS_ERROR = -1000, + CONTEXT_VALIDATION_FAILURE = -2000, +} hash_spec_result; + typedef struct _php_hashcontext_object php_hashcontext_object; typedef void (*php_hash_init_func_t)(void *context, HashTable *args); typedef void (*php_hash_update_func_t)(void *context, const unsigned char *buf, size_t count); typedef void (*php_hash_final_func_t)(unsigned char *digest, void *context); typedef zend_result (*php_hash_copy_func_t)(const void *ops, const void *orig_context, void *dest_context); -typedef zend_result (*php_hash_serialize_func_t)(const php_hashcontext_object *hash, zend_long *magic, zval *zv); -typedef int (*php_hash_unserialize_func_t)(php_hashcontext_object *hash, zend_long magic, const zval *zv); +typedef hash_spec_result (*php_hash_serialize_func_t)(const php_hashcontext_object *hash, zend_long *magic, zval *zv); +typedef hash_spec_result (*php_hash_unserialize_func_t)(php_hashcontext_object *hash, zend_long magic, const zval *zv); typedef struct _php_hash_ops { const char *algo; @@ -148,10 +156,10 @@ extern PHP_HASH_API zend_class_entry *php_hashcontext_ce; PHP_HASH_API const php_hash_ops *php_hash_fetch_ops(zend_string *algo); PHP_HASH_API void php_hash_register_algo(const char *algo, const php_hash_ops *ops); PHP_HASH_API zend_result php_hash_copy(const void *ops, const void *orig_context, void *dest_context); -PHP_HASH_API zend_result php_hash_serialize(const php_hashcontext_object *context, zend_long *magic, zval *zv); -PHP_HASH_API int php_hash_unserialize(php_hashcontext_object *context, zend_long magic, const zval *zv); -PHP_HASH_API zend_result php_hash_serialize_spec(const php_hashcontext_object *context, zval *zv, const char *spec); -PHP_HASH_API int php_hash_unserialize_spec(php_hashcontext_object *hash, const zval *zv, const char *spec); +PHP_HASH_API hash_spec_result php_hash_serialize(const php_hashcontext_object *context, zend_long *magic, zval *zv); +PHP_HASH_API hash_spec_result php_hash_unserialize(php_hashcontext_object *context, zend_long magic, const zval *zv); +PHP_HASH_API hash_spec_result php_hash_serialize_spec(const php_hashcontext_object *context, zval *zv, const char *spec); +PHP_HASH_API hash_spec_result php_hash_unserialize_spec(php_hashcontext_object *hash, const zval *zv, const char *spec); static inline void *php_hash_alloc_context(const php_hash_ops *ops) { /* Zero out context memory so serialization doesn't expose internals */ diff --git a/ext/iconv/iconv.c b/ext/iconv/iconv.c index 157ee41a11a..092e1566987 100644 --- a/ext/iconv/iconv.c +++ b/ext/iconv/iconv.c @@ -2571,7 +2571,6 @@ static const php_stream_filter_ops php_iconv_stream_filter_ops = { /* {{{ php_iconv_stream_filter_create */ static php_stream_filter *php_iconv_stream_filter_factory_create(const char *name, zval *params, uint8_t persistent) { - php_stream_filter *retval = NULL; php_iconv_stream_filter *inst; const char *from_charset = NULL, *to_charset = NULL; size_t from_charset_len, to_charset_len; @@ -2602,12 +2601,7 @@ static php_stream_filter *php_iconv_stream_filter_factory_create(const char *nam return NULL; } - if (NULL == (retval = php_stream_filter_alloc(&php_iconv_stream_filter_ops, inst, persistent))) { - php_iconv_stream_filter_dtor(inst); - pefree(inst, persistent); - } - - return retval; + return php_stream_filter_alloc(&php_iconv_stream_filter_ops, inst, persistent); } /* }}} */ diff --git a/ext/intl/breakiterator/breakiterator_iterators.cpp b/ext/intl/breakiterator/breakiterator_iterators.cpp index 6817f52ffb0..34176bf90e5 100644 --- a/ext/intl/breakiterator/breakiterator_iterators.cpp +++ b/ext/intl/breakiterator/breakiterator_iterators.cpp @@ -43,7 +43,7 @@ inline BreakIterator *_breakiter_prolog(zend_object_iterator *iter) if (bio->biter == NULL) { intl_errors_set(BREAKITER_ERROR_P(bio), U_INVALID_STATE_ERROR, "The BreakIterator object backing the PHP iterator is not " - "properly constructed", 0); + "properly constructed"); } return bio->biter; } diff --git a/ext/intl/breakiterator/breakiterator_methods.cpp b/ext/intl/breakiterator/breakiterator_methods.cpp index 56a3a35c97f..c9791d4b23a 100644 --- a/ext/intl/breakiterator/breakiterator_methods.cpp +++ b/ext/intl/breakiterator/breakiterator_methods.cpp @@ -41,14 +41,13 @@ U_CFUNC PHP_METHOD(IntlBreakIterator, __construct) 0 ); } -static void _breakiter_factory(const char *func_name, - BreakIterator *(*func)(const Locale&, UErrorCode&), - INTERNAL_FUNCTION_PARAMETERS) +static void _breakiter_factory( + BreakIterator *(*func)(const Locale&, UErrorCode&), + INTERNAL_FUNCTION_PARAMETERS) { BreakIterator *biter; char *locale_str = NULL; size_t dummy; - char *msg; UErrorCode status = UErrorCode(); intl_error_reset(NULL); @@ -64,10 +63,7 @@ static void _breakiter_factory(const char *func_name, biter = func(Locale::createFromName(locale_str), status); intl_error_set_code(NULL, status); if (U_FAILURE(status)) { - spprintf(&msg, 0, "%s: error creating BreakIterator", - func_name); - intl_error_set_custom_msg(NULL, msg, 1); - efree(msg); + intl_error_set_custom_msg(NULL, "error creating BreakIterator"); RETURN_NULL(); } @@ -76,35 +72,35 @@ static void _breakiter_factory(const char *func_name, U_CFUNC PHP_METHOD(IntlBreakIterator, createWordInstance) { - _breakiter_factory("breakiter_create_word_instance", + _breakiter_factory( &BreakIterator::createWordInstance, INTERNAL_FUNCTION_PARAM_PASSTHRU); } U_CFUNC PHP_METHOD(IntlBreakIterator, createLineInstance) { - _breakiter_factory("breakiter_create_line_instance", + _breakiter_factory( &BreakIterator::createLineInstance, INTERNAL_FUNCTION_PARAM_PASSTHRU); } U_CFUNC PHP_METHOD(IntlBreakIterator, createCharacterInstance) { - _breakiter_factory("breakiter_create_character_instance", + _breakiter_factory( &BreakIterator::createCharacterInstance, INTERNAL_FUNCTION_PARAM_PASSTHRU); } U_CFUNC PHP_METHOD(IntlBreakIterator, createSentenceInstance) { - _breakiter_factory("breakiter_create_sentence_instance", + _breakiter_factory( &BreakIterator::createSentenceInstance, INTERNAL_FUNCTION_PARAM_PASSTHRU); } U_CFUNC PHP_METHOD(IntlBreakIterator, createTitleInstance) { - _breakiter_factory("breakiter_create_title_instance", + _breakiter_factory( &BreakIterator::createTitleInstance, INTERNAL_FUNCTION_PARAM_PASSTHRU); } @@ -149,12 +145,11 @@ U_CFUNC PHP_METHOD(IntlBreakIterator, setText) BREAKITER_METHOD_FETCH_OBJECT; ut = utext_openUTF8(ut, ZSTR_VAL(text), ZSTR_LEN(text), BREAKITER_ERROR_CODE_P(bio)); - INTL_METHOD_CHECK_STATUS(bio, "breakiter_set_text: error opening UText"); + INTL_METHOD_CHECK_STATUS(bio, "error opening UText"); bio->biter->setText(ut, BREAKITER_ERROR_CODE(bio)); utext_close(ut); /* ICU shallow clones the UText */ - INTL_METHOD_CHECK_STATUS(bio, "breakiter_set_text: error calling " - "BreakIterator::setText()"); + INTL_METHOD_CHECK_STATUS(bio, "error calling BreakIterator::setText()"); /* When ICU clones the UText, it does not copy the buffer, so we have to * keep the string buffer around by holding a reference to its zval. This @@ -302,10 +297,10 @@ U_CFUNC PHP_METHOD(IntlBreakIterator, getLocale) Z_PARAM_LONG(locale_type) ZEND_PARSE_PARAMETERS_END(); - /* Change to ValueError? */ + /* TODO: Change to ValueError? */ if (locale_type != ULOC_ACTUAL_LOCALE && locale_type != ULOC_VALID_LOCALE) { intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, - "breakiter_get_locale: invalid locale type", 0); + "invalid locale type"); RETURN_FALSE; } @@ -313,8 +308,7 @@ U_CFUNC PHP_METHOD(IntlBreakIterator, getLocale) Locale locale = bio->biter->getLocale((ULocDataLocaleType)locale_type, BREAKITER_ERROR_CODE(bio)); - INTL_METHOD_CHECK_STATUS(bio, - "breakiter_get_locale: Call to ICU method has failed"); + INTL_METHOD_CHECK_STATUS(bio, "Call to ICU method has failed"); RETURN_STRING(locale.getName()); } diff --git a/ext/intl/breakiterator/rulebasedbreakiterator_methods.cpp b/ext/intl/breakiterator/rulebasedbreakiterator_methods.cpp index c84972fe5b9..a7c322b1d81 100644 --- a/ext/intl/breakiterator/rulebasedbreakiterator_methods.cpp +++ b/ext/intl/breakiterator/rulebasedbreakiterator_methods.cpp @@ -32,17 +32,16 @@ static inline RuleBasedBreakIterator *fetch_rbbi(BreakIterator_object *bio) { return (RuleBasedBreakIterator*)bio->biter; } -static void _php_intlrbbi_constructor_body(INTERNAL_FUNCTION_PARAMETERS, zend_error_handling *error_handling, bool *error_handling_replaced) +U_CFUNC PHP_METHOD(IntlRuleBasedBreakIterator, __construct) { - char *rules; - size_t rules_len; - bool compiled = false; - UErrorCode status = U_ZERO_ERROR; + zend_string *rules; + bool compiled = false; + UErrorCode status = U_ZERO_ERROR; BREAKITER_METHOD_INIT_VARS; object = ZEND_THIS; ZEND_PARSE_PARAMETERS_START(1, 2) - Z_PARAM_STRING(rules, rules_len) + Z_PARAM_STR(rules) Z_PARAM_OPTIONAL Z_PARAM_BOOL(compiled) ZEND_PARSE_PARAMETERS_END(); @@ -53,20 +52,14 @@ static void _php_intlrbbi_constructor_body(INTERNAL_FUNCTION_PARAMETERS, zend_er RETURN_THROWS(); } - zend_replace_error_handling(EH_THROW, IntlException_ce_ptr, error_handling); - *error_handling_replaced = 1; - - // instantiation of ICU object RuleBasedBreakIterator *rbbi; if (!compiled) { UnicodeString rulesStr; UParseError parseError = UParseError(); - if (intl_stringFromChar(rulesStr, rules, rules_len, &status) - == FAILURE) { + if (intl_stringFromChar(rulesStr, ZSTR_VAL(rules), ZSTR_LEN(rules), &status) == FAILURE) { zend_throw_exception(IntlException_ce_ptr, - "IntlRuleBasedBreakIterator::__construct(): " - "rules were not a valid UTF-8 string", 0); + "IntlRuleBasedBreakIterator::__construct(): rules were not a valid UTF-8 string", 0); RETURN_THROWS(); } @@ -84,29 +77,16 @@ static void _php_intlrbbi_constructor_body(INTERNAL_FUNCTION_PARAMETERS, zend_er RETURN_THROWS(); } } else { // compiled - rbbi = new RuleBasedBreakIterator((uint8_t*)rules, rules_len, status); + rbbi = new RuleBasedBreakIterator(reinterpret_cast(ZSTR_VAL(rules)), ZSTR_LEN(rules), status); if (U_FAILURE(status)) { zend_throw_exception(IntlException_ce_ptr, - "IntlRuleBasedBreakIterator::__construct(): " - "unable to create instance from compiled rules", 0); + "IntlRuleBasedBreakIterator::__construct(): unable to create instance from compiled rules", 0); delete rbbi; RETURN_THROWS(); } } - breakiterator_object_create(return_value, rbbi, 0); -} - -U_CFUNC PHP_METHOD(IntlRuleBasedBreakIterator, __construct) -{ - zend_error_handling error_handling; - bool error_handling_replaced = 0; - - return_value = ZEND_THIS; - _php_intlrbbi_constructor_body(INTERNAL_FUNCTION_PARAM_PASSTHRU, &error_handling, &error_handling_replaced); - if (error_handling_replaced) { - zend_restore_error_handling(&error_handling); - } + breakiterator_object_create(object, rbbi, false); } U_CFUNC PHP_METHOD(IntlRuleBasedBreakIterator, getRules) @@ -125,8 +105,7 @@ U_CFUNC PHP_METHOD(IntlRuleBasedBreakIterator, getRules) if (!u8str) { intl_errors_set(BREAKITER_ERROR_P(bio), BREAKITER_ERROR_CODE(bio), - "rbbi_hash_code: Error converting result to UTF-8 string", - 0); + "Error converting result to UTF-8 string"); RETURN_FALSE; } RETVAL_STR(u8str); @@ -164,8 +143,7 @@ U_CFUNC PHP_METHOD(IntlRuleBasedBreakIterator, getRuleStatusVec) BREAKITER_ERROR_CODE(bio)); if (U_FAILURE(BREAKITER_ERROR_CODE(bio))) { intl_errors_set(BREAKITER_ERROR_P(bio), BREAKITER_ERROR_CODE(bio), - "rbbi_get_rule_status_vec: failed obtaining the status values", - 0); + "failed obtaining the status values"); RETURN_FALSE; } @@ -189,8 +167,7 @@ U_CFUNC PHP_METHOD(IntlRuleBasedBreakIterator, getBinaryRules) if (rules_len > INT_MAX - 1) { intl_errors_set(BREAKITER_ERROR_P(bio), BREAKITER_ERROR_CODE(bio), - "rbbi_get_binary_rules: the rules are too large", - 0); + "the rules are too large"); RETURN_FALSE; } diff --git a/ext/intl/calendar/calendar.stub.php b/ext/intl/calendar/calendar.stub.php index 078ecb0c2da..56602da0ec2 100644 --- a/ext/intl/calendar/calendar.stub.php +++ b/ext/intl/calendar/calendar.stub.php @@ -90,11 +90,10 @@ class IntlCalendar private function __construct() {} /** - * @param IntlTimeZone|DateTimeZone|string|null $timezone * @tentative-return-type * @alias intlcal_create_instance */ - public static function createInstance($timezone = null, ?string $locale = null): ?IntlCalendar {} + public static function createInstance(IntlTimeZone|DateTimeZone|string|null $timezone = null, ?string $locale = null): ?IntlCalendar {} /** * @tentative-return-type @@ -355,11 +354,9 @@ class IntlCalendar public function setTime(float $timestamp): bool {} /** - * @param IntlTimeZone|DateTimeZone|string|null $timezone * @tentative-return-type - * @alias intlcal_set_time_zone */ - public function setTimeZone($timezone): bool {} + public function setTimeZone(IntlTimeZone|DateTimeZone|string|null $timezone): bool {} /** * @tentative-return-type diff --git a/ext/intl/calendar/calendar_arginfo.h b/ext/intl/calendar/calendar_arginfo.h index 9e050539b2e..415113b613a 100644 --- a/ext/intl/calendar/calendar_arginfo.h +++ b/ext/intl/calendar/calendar_arginfo.h @@ -1,11 +1,11 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: c014b88c9b6aa145ea20cc1f3fd719fe9f3d6966 */ + * Stub hash: 2fc12d1fde65efbec4305f4934a3f4b25282a552 */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_IntlCalendar___construct, 0, 0, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_INFO_EX(arginfo_class_IntlCalendar_createInstance, 0, 0, IntlCalendar, 1) - ZEND_ARG_INFO_WITH_DEFAULT_VALUE(0, timezone, "null") + ZEND_ARG_OBJ_TYPE_MASK(0, timezone, IntlTimeZone|DateTimeZone, MAY_BE_STRING|MAY_BE_NULL, "null") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, locale, IS_STRING, 1, "null") ZEND_END_ARG_INFO() @@ -165,7 +165,7 @@ ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_IntlCalendar_set ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_IntlCalendar_setTimeZone, 0, 1, _IS_BOOL, 0) - ZEND_ARG_INFO(0, timezone) + ZEND_ARG_OBJ_TYPE_MASK(0, timezone, IntlTimeZone|DateTimeZone, MAY_BE_STRING|MAY_BE_NULL, NULL) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_IntlCalendar_toDateTime, 0, 0, DateTime, MAY_BE_FALSE) @@ -249,7 +249,7 @@ ZEND_FUNCTION(intlcal_set_lenient); ZEND_FUNCTION(intlcal_set_repeated_wall_time_option); ZEND_FUNCTION(intlcal_set_skipped_wall_time_option); ZEND_FUNCTION(intlcal_set_time); -ZEND_FUNCTION(intlcal_set_time_zone); +ZEND_METHOD(IntlCalendar, setTimeZone); ZEND_FUNCTION(intlcal_to_date_time); ZEND_METHOD(IntlGregorianCalendar, createFromDate); ZEND_METHOD(IntlGregorianCalendar, createFromDateTime); @@ -305,7 +305,7 @@ static const zend_function_entry class_IntlCalendar_methods[] = { ZEND_RAW_FENTRY("setRepeatedWallTimeOption", zif_intlcal_set_repeated_wall_time_option, arginfo_class_IntlCalendar_setRepeatedWallTimeOption, ZEND_ACC_PUBLIC, NULL, NULL) ZEND_RAW_FENTRY("setSkippedWallTimeOption", zif_intlcal_set_skipped_wall_time_option, arginfo_class_IntlCalendar_setSkippedWallTimeOption, ZEND_ACC_PUBLIC, NULL, NULL) ZEND_RAW_FENTRY("setTime", zif_intlcal_set_time, arginfo_class_IntlCalendar_setTime, ZEND_ACC_PUBLIC, NULL, NULL) - ZEND_RAW_FENTRY("setTimeZone", zif_intlcal_set_time_zone, arginfo_class_IntlCalendar_setTimeZone, ZEND_ACC_PUBLIC, NULL, NULL) + ZEND_ME(IntlCalendar, setTimeZone, arginfo_class_IntlCalendar_setTimeZone, ZEND_ACC_PUBLIC) ZEND_RAW_FENTRY("toDateTime", zif_intlcal_to_date_time, arginfo_class_IntlCalendar_toDateTime, ZEND_ACC_PUBLIC, NULL, NULL) ZEND_FE_END }; diff --git a/ext/intl/calendar/calendar_class.cpp b/ext/intl/calendar/calendar_class.cpp index f0582c64d2b..326b5475b73 100644 --- a/ext/intl/calendar/calendar_class.cpp +++ b/ext/intl/calendar/calendar_class.cpp @@ -71,7 +71,7 @@ U_CFUNC void calendar_object_construct(zval *object, CALENDAR_METHOD_FETCH_OBJECT_NO_CHECK; //populate to from object assert(co->ucal == NULL); - co->ucal = (Calendar*)calendar; + co->ucal = calendar; } /* {{{ clone handler for Calendar */ diff --git a/ext/intl/calendar/calendar_methods.cpp b/ext/intl/calendar/calendar_methods.cpp index 9b7a37c0df5..c404286fe09 100644 --- a/ext/intl/calendar/calendar_methods.cpp +++ b/ext/intl/calendar/calendar_methods.cpp @@ -72,22 +72,21 @@ U_CFUNC PHP_METHOD(IntlCalendar, __construct) U_CFUNC PHP_FUNCTION(intlcal_create_instance) { - zval *zv_timezone = NULL; + zend_object *timezone_object = nullptr; + zend_string *timezone_string = nullptr; char *locale_str = NULL; size_t locale_len = 0; - TimeZone *timeZone; UErrorCode status = U_ZERO_ERROR; intl_error_reset(NULL); ZEND_PARSE_PARAMETERS_START(0, 2) Z_PARAM_OPTIONAL - Z_PARAM_ZVAL(zv_timezone) + Z_PARAM_OBJ_OR_STR_OR_NULL(timezone_object, timezone_string) Z_PARAM_STRING_OR_NULL(locale_str, locale_len) ZEND_PARSE_PARAMETERS_END(); - timeZone = timezone_process_timezone_argument(zv_timezone, NULL, - "intlcal_create_instance"); - if (timeZone == NULL) { + TimeZone *timeZone = timezone_process_timezone_argument(timezone_object, timezone_string, nullptr); + if (timeZone == nullptr) { RETURN_NULL(); } @@ -99,7 +98,7 @@ U_CFUNC PHP_FUNCTION(intlcal_create_instance) Locale::createFromName(locale_str), status); if (UNEXPECTED(cal == NULL)) { delete timeZone; - intl_error_set(NULL, status, "Error creating ICU Calendar object", 0); + intl_error_set(NULL, status, "Error creating ICU Calendar object"); RETURN_NULL(); } @@ -179,8 +178,8 @@ U_CFUNC PHP_FUNCTION(intlcal_get_keyword_values_for_locale) Locale::createFromName(locale), (UBool)commonly_used, status); if (se == NULL) { - intl_error_set(NULL, status, "intlcal_get_keyword_values_for_locale: " - "error calling underlying method", 0); + intl_error_set(NULL, status, + "error calling underlying method"); RETURN_FALSE; } @@ -252,8 +251,7 @@ U_CFUNC PHP_FUNCTION(intlcal_get_time) CALENDAR_METHOD_FETCH_OBJECT; UDate result = co->ucal->getTime(CALENDAR_ERROR_CODE(co)); - INTL_METHOD_CHECK_STATUS(co, - "intlcal_get_time: error calling ICU Calendar::getTime"); + INTL_METHOD_CHECK_STATUS(co, "error calling ICU Calendar::getTime"); RETURN_DOUBLE((double)result); } @@ -293,31 +291,33 @@ U_CFUNC PHP_FUNCTION(intlcal_add) CALENDAR_METHOD_FETCH_OBJECT; co->ucal->add((UCalendarDateFields)field, (int32_t)amount, CALENDAR_ERROR_CODE(co)); - INTL_METHOD_CHECK_STATUS(co, "intlcal_add: Call to underlying method failed"); + INTL_METHOD_CHECK_STATUS(co, "Call to underlying method failed"); RETURN_TRUE; } +/* {{{ Set formatter's timezone. */ U_CFUNC PHP_FUNCTION(intlcal_set_time_zone) { - zval *zv_timezone; - TimeZone *timeZone; + zend_object *timezone_object = nullptr; + zend_string *timezone_string = nullptr; + CALENDAR_METHOD_INIT_VARS; - if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), - "Oz!", &object, Calendar_ce_ptr, &zv_timezone) == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_START(2, 2) + Z_PARAM_OBJECT_OF_CLASS(object, Calendar_ce_ptr) + Z_PARAM_OBJ_OR_STR_OR_NULL(timezone_object, timezone_string) + ZEND_PARSE_PARAMETERS_END(); CALENDAR_METHOD_FETCH_OBJECT; - if (zv_timezone == NULL) { + if (timezone_object == nullptr && timezone_string == nullptr) { RETURN_TRUE; /* the method does nothing if passed null */ } - timeZone = timezone_process_timezone_argument(zv_timezone, - CALENDAR_ERROR_P(co), "intlcal_set_time_zone"); - if (timeZone == NULL) { + TimeZone *timeZone = timezone_process_timezone_argument( + timezone_object, timezone_string, CALENDAR_ERROR_P(co)); + if (timeZone == nullptr) { RETURN_FALSE; } @@ -326,6 +326,34 @@ U_CFUNC PHP_FUNCTION(intlcal_set_time_zone) RETURN_TRUE; } +U_CFUNC PHP_METHOD(IntlCalendar, setTimeZone) +{ + zend_object *timezone_object = nullptr; + zend_string *timezone_string = nullptr; + + CALENDAR_METHOD_INIT_VARS; + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_OBJ_OR_STR_OR_NULL(timezone_object, timezone_string) + ZEND_PARSE_PARAMETERS_END(); + + object = ZEND_THIS; + CALENDAR_METHOD_FETCH_OBJECT; + + if (timezone_object == nullptr && timezone_string == nullptr) { + RETURN_TRUE; /* the method does nothing if passed null */ + } + + TimeZone *timeZone = timezone_process_timezone_argument( + timezone_object, timezone_string, CALENDAR_ERROR_P(co)); + if (timeZone == nullptr) { + RETURN_FALSE; + } + + co->ucal->adoptTimeZone(timeZone); + + RETURN_TRUE; +} static void _php_intlcal_before_after( UBool (Calendar::*func)(const Calendar&, UErrorCode&) const, @@ -350,7 +378,7 @@ static void _php_intlcal_before_after( } UBool res = (co->ucal->*func)(*when_co->ucal, CALENDAR_ERROR_CODE(co)); - INTL_METHOD_CHECK_STATUS(co, "intlcal_before/after: Error calling ICU method"); + INTL_METHOD_CHECK_STATUS(co, "Error calling ICU method"); RETURN_BOOL((int)res); } @@ -490,7 +518,7 @@ U_CFUNC PHP_FUNCTION(intlcal_roll) co->ucal->roll((UCalendarDateFields)field, (int32_t)value, CALENDAR_ERROR_CODE(co)); - INTL_METHOD_CHECK_STATUS(co, "intlcal_roll: Error calling ICU Calendar::roll"); + INTL_METHOD_CHECK_STATUS(co, "Error calling ICU Calendar::roll"); RETURN_TRUE; } @@ -536,8 +564,7 @@ U_CFUNC PHP_FUNCTION(intlcal_field_difference) int32_t result = co->ucal->fieldDifference((UDate)when, (UCalendarDateFields)field, CALENDAR_ERROR_CODE(co)); - INTL_METHOD_CHECK_STATUS(co, - "intlcal_field_difference: Call to ICU method has failed"); + INTL_METHOD_CHECK_STATUS(co, "Call to ICU method has failed"); RETURN_LONG((zend_long)result); } @@ -570,8 +597,7 @@ U_CFUNC PHP_FUNCTION(intlcal_get_day_of_week_type) int32_t result = co->ucal->getDayOfWeekType( (UCalendarDaysOfWeek)dow, CALENDAR_ERROR_CODE(co)); - INTL_METHOD_CHECK_STATUS(co, - "intlcal_get_day_of_week_type: Call to ICU method has failed"); + INTL_METHOD_CHECK_STATUS(co, "Call to ICU method has failed"); RETURN_LONG((zend_long)result); } @@ -588,8 +614,7 @@ U_CFUNC PHP_FUNCTION(intlcal_get_first_day_of_week) CALENDAR_METHOD_FETCH_OBJECT; int32_t result = co->ucal->getFirstDayOfWeek(CALENDAR_ERROR_CODE(co)); - INTL_METHOD_CHECK_STATUS(co, - "intlcal_get_first_day_of_week: Call to ICU method has failed"); + INTL_METHOD_CHECK_STATUS(co, "Call to ICU method has failed"); RETURN_LONG((zend_long)result); } @@ -647,8 +672,7 @@ U_CFUNC PHP_FUNCTION(intlcal_get_locale) Locale locale = co->ucal->getLocale((ULocDataLocaleType)locale_type, CALENDAR_ERROR_CODE(co)); - INTL_METHOD_CHECK_STATUS(co, - "intlcal_get_locale: Call to ICU method has failed"); + INTL_METHOD_CHECK_STATUS(co, "Call to ICU method has failed"); RETURN_STRING(locale.getName()); } @@ -671,8 +695,8 @@ U_CFUNC PHP_FUNCTION(intlcal_get_minimal_days_in_first_week) CALENDAR_METHOD_FETCH_OBJECT; uint8_t result = co->ucal->getMinimalDaysInFirstWeek(); - INTL_METHOD_CHECK_STATUS(co, - "intlcal_get_first_day_of_week: Call to ICU method has failed"); /* TODO Is it really a failure? */ + /* TODO Is it really a failure? */ + INTL_METHOD_CHECK_STATUS(co, "Call to ICU method has failed"); RETURN_LONG((zend_long)result); } @@ -697,7 +721,7 @@ U_CFUNC PHP_FUNCTION(intlcal_get_time_zone) TimeZone *tz = co->ucal->getTimeZone().clone(); if (UNEXPECTED(tz == NULL)) { intl_errors_set(CALENDAR_ERROR_P(co), U_MEMORY_ALLOCATION_ERROR, - "intlcal_get_time_zone: could not clone TimeZone", 0); + "could not clone TimeZone"); RETURN_FALSE; } @@ -734,8 +758,7 @@ U_CFUNC PHP_FUNCTION(intlcal_get_weekend_transition) int32_t res = co->ucal->getWeekendTransition((UCalendarDaysOfWeek)dow, CALENDAR_ERROR_CODE(co)); - INTL_METHOD_CHECK_STATUS(co, "intlcal_get_weekend_transition: " - "Error calling ICU method"); + INTL_METHOD_CHECK_STATUS(co, "Error calling ICU method"); RETURN_LONG((zend_long)res); } @@ -752,8 +775,7 @@ U_CFUNC PHP_FUNCTION(intlcal_in_daylight_time) CALENDAR_METHOD_FETCH_OBJECT; UBool ret = co->ucal->inDaylightTime(CALENDAR_ERROR_CODE(co)); - INTL_METHOD_CHECK_STATUS(co, "intlcal_in_daylight_time: " - "Error calling ICU method"); + INTL_METHOD_CHECK_STATUS(co, "Error calling ICU method"); RETURN_BOOL((int)ret); } @@ -829,8 +851,7 @@ U_CFUNC PHP_FUNCTION(intlcal_is_weekend) RETURN_BOOL((int)co->ucal->isWeekend()); } else { UBool ret = co->ucal->isWeekend((UDate)date, CALENDAR_ERROR_CODE(co)); - INTL_METHOD_CHECK_STATUS(co, "intlcal_is_weekend: " - "Error calling ICU method"); + INTL_METHOD_CHECK_STATUS(co, "Error calling ICU method"); RETURN_BOOL((int)ret); } } @@ -915,7 +936,7 @@ U_CFUNC PHP_FUNCTION(intlcal_equals) } UBool result = co->ucal->equals(*other_co->ucal, CALENDAR_ERROR_CODE(co)); - INTL_METHOD_CHECK_STATUS(co, "intlcal_equals: error calling ICU Calendar::equals"); + INTL_METHOD_CHECK_STATUS(co, "error calling ICU Calendar::equals"); RETURN_BOOL((int)result); } @@ -1028,16 +1049,14 @@ U_CFUNC PHP_FUNCTION(intlcal_from_date_time) datetime = php_date_obj_from_obj(date_obj); if (!datetime->time) { intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, - "intlcal_from_date_time: DateTime object is unconstructed", - 0); + "DateTime object is unconstructed"); goto error; } zend_call_method_with_0_params(date_obj, php_date_get_date_ce(), NULL, "gettimestamp", &zv_timestamp); if (Z_TYPE(zv_timestamp) != IS_LONG) { intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, - "intlcal_from_date_time: bad DateTime; call to " - "DateTime::getTimestamp() failed", 0); + "bad DateTime; call to DateTime::getTimestamp() failed"); zval_ptr_dtor(&zv_timestamp); goto error; } @@ -1046,7 +1065,7 @@ U_CFUNC PHP_FUNCTION(intlcal_from_date_time) timeZone = TimeZone::getGMT()->clone(); } else { timeZone = timezone_convert_datetimezone(datetime->time->zone_type, - datetime, 1, NULL, "intlcal_from_date_time"); + datetime, 1, NULL); if (timeZone == NULL) { goto error; } @@ -1060,16 +1079,16 @@ U_CFUNC PHP_FUNCTION(intlcal_from_date_time) Locale::createFromName(locale_str), status); if (UNEXPECTED(cal == NULL)) { delete timeZone; - intl_error_set(NULL, status, "intlcal_from_date_time: " - "error creating ICU Calendar object", 0); + intl_error_set(NULL, status, + "error creating ICU Calendar object"); goto error; } cal->setTime(((UDate)Z_LVAL(zv_timestamp)) * 1000., status); if (U_FAILURE(status)) { /* time zone was adopted by cal; should not be deleted here */ delete cal; - intl_error_set(NULL, status, "intlcal_from_date_time: " - "error creating ICU Calendar::setTime()", 0); + intl_error_set(NULL, status, + "error creating ICU Calendar::setTime()"); goto error; } @@ -1105,8 +1124,7 @@ U_CFUNC PHP_FUNCTION(intlcal_to_date_time) if (UNEXPECTED(date > (double)U_INT64_MAX || date < (double)U_INT64_MIN)) { intl_errors_set(CALENDAR_ERROR_P(co), U_ILLEGAL_ARGUMENT_ERROR, - "intlcal_to_date_time: The calendar date is out of the " - "range for a 64-bit integer", 0); + "The calendar date is out of the range for a 64-bit integer"); RETURN_FALSE; } @@ -1119,7 +1137,7 @@ U_CFUNC PHP_FUNCTION(intlcal_to_date_time) /* Now get the time zone */ const TimeZone& tz = co->ucal->getTimeZone(); zval *timezone_zval = timezone_convert_to_datetimezone( - &tz, CALENDAR_ERROR_P(co), "intlcal_to_date_time", &tmp); + &tz, CALENDAR_ERROR_P(co), &tmp); if (timezone_zval == NULL) { zval_ptr_dtor(&ts_zval); RETURN_FALSE; @@ -1146,8 +1164,7 @@ U_CFUNC PHP_FUNCTION(intlcal_to_date_time) &retval, timezone_zval); if (Z_ISUNDEF(retval) || Z_TYPE(retval) == IS_FALSE) { intl_errors_set(CALENDAR_ERROR_P(co), U_ILLEGAL_ARGUMENT_ERROR, - "intlcal_to_date_time: call to DateTime::setTimeZone has failed", - 1); + "call to DateTime::setTimeZone has failed"); zval_ptr_dtor(return_value); RETVAL_FALSE; goto error; diff --git a/ext/intl/calendar/gregoriancalendar_methods.cpp b/ext/intl/calendar/gregoriancalendar_methods.cpp index d6b8f0602dd..0cc3a94d4c5 100644 --- a/ext/intl/calendar/gregoriancalendar_methods.cpp +++ b/ext/intl/calendar/gregoriancalendar_methods.cpp @@ -17,6 +17,7 @@ #endif #include "../intl_cppshims.h" +#include #include #include @@ -46,16 +47,14 @@ using icu::StringPiece; } static inline GregorianCalendar *fetch_greg(Calendar_object *co) { - return (GregorianCalendar*)co->ucal; + return static_cast(co->ucal); } static bool set_gregorian_calendar_time_zone(GregorianCalendar *gcal, UErrorCode status) { if (U_FAILURE(status)) { intl_error_set(NULL, status, - "IntlGregorianCalendar: Error creating ICU GregorianCalendar from date", - 0 - ); + "Error creating ICU GregorianCalendar from date"); return false; } @@ -64,10 +63,8 @@ static bool set_gregorian_calendar_time_zone(GregorianCalendar *gcal, UErrorCode UnicodeString tzstr = UnicodeString::fromUTF8(StringPiece(tzinfo->name)); if (tzstr.isBogus()) { intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, - "IntlGregorianCalendar: Could not create UTF-8 string " - "from PHP's default timezone name (see date_default_timezone_get())", - 0 - ); + "Could not create UTF-8 string from PHP's default timezone " + "name (see date_default_timezone_get())"); return false; } @@ -78,10 +75,10 @@ static bool set_gregorian_calendar_time_zone(GregorianCalendar *gcal, UErrorCode return true; } -static void _php_intlgregcal_constructor_body( - INTERNAL_FUNCTION_PARAMETERS, bool is_constructor, zend_error_handling *error_handling, bool *error_handling_replaced) +static void _php_intlgregcal_constructor_body(INTERNAL_FUNCTION_PARAMETERS, bool is_constructor) { - zval *tz_object = NULL; + zend_object *timezone_object = nullptr; + zend_string *timezone_string = nullptr; zval args_a[6], *args = &args_a[0]; char *locale = NULL; @@ -116,25 +113,28 @@ static void _php_intlgregcal_constructor_body( // argument parsing if (variant <= 2) { - if (zend_parse_parameters(MIN(ZEND_NUM_ARGS(), 2), - "|z!s!", &tz_object, &locale, &locale_len) == FAILURE) { - RETURN_THROWS(); - } - } - if (variant > 2 && zend_parse_parameters(ZEND_NUM_ARGS(), - "lll|lll", &largs[0], &largs[1], &largs[2], &largs[3], &largs[4], - &largs[5]) == FAILURE) { - RETURN_THROWS(); + /* These dummy variables are needed because the 2 param constructor allows trailing nulls... */ + zval *dummy1, *dummy2, *dummy3, *dummy4; + ZEND_PARSE_PARAMETERS_START(0, 6) + Z_PARAM_OPTIONAL + Z_PARAM_OBJ_OR_STR_OR_NULL(timezone_object, timezone_string) + Z_PARAM_STRING_OR_NULL(locale, locale_len) + Z_PARAM_ZVAL(dummy1) + Z_PARAM_ZVAL(dummy2) + Z_PARAM_ZVAL(dummy3) + Z_PARAM_ZVAL(dummy4) + ZEND_PARSE_PARAMETERS_END(); } - - if (error_handling != NULL) { - zend_replace_error_handling(EH_THROW, IntlException_ce_ptr, error_handling); - *error_handling_replaced = 1; + if (variant > 2 + && zend_parse_parameters(ZEND_NUM_ARGS(), "lll|lll", + &largs[0], &largs[1], &largs[2], &largs[3], &largs[4], &largs[5]) == FAILURE + ) { + RETURN_THROWS(); } // instantion of ICU object Calendar_object *co = Z_INTL_CALENDAR_P(return_value); - GregorianCalendar *gcal = NULL; + std::unique_ptr gcal; if (co->ucal) { zend_throw_error(NULL, "IntlGregorianCalendar object is already constructed"); @@ -143,9 +143,9 @@ static void _php_intlgregcal_constructor_body( if (variant <= 2) { // From timezone and locale (0 to 2 arguments) - TimeZone *tz = timezone_process_timezone_argument(tz_object, NULL, - "intlgregcal_create_instance"); - if (tz == NULL) { + TimeZone *tz = timezone_process_timezone_argument(timezone_object, timezone_string, nullptr); + if (tz == nullptr) { + // TODO: Exception should always occur already? if (!EG(exception)) { zend_throw_exception(IntlException_ce_ptr, "Constructor failed", 0); } @@ -159,15 +159,12 @@ static void _php_intlgregcal_constructor_body( locale = const_cast(intl_locale_get_default()); } - gcal = new GregorianCalendar(tz, Locale::createFromName(locale), - status); + gcal = std::unique_ptr(new GregorianCalendar(tz, Locale::createFromName(locale), + status)); // Should this throw? if (U_FAILURE(status)) { - intl_error_set(NULL, status, "intlgregcal_create_instance: error " - "creating ICU GregorianCalendar from time zone and locale", 0); - if (gcal) { - delete gcal; - } + intl_error_set(NULL, status, "error creating ICU " + "GregorianCalendar from time zone and locale"); delete tz; if (!is_constructor) { zval_ptr_dtor(return_value); @@ -177,26 +174,28 @@ static void _php_intlgregcal_constructor_body( } } else { // From date/time (3, 5 or 6 arguments) + GregorianCalendar *tmp; for (int i = 0; i < variant; i++) { ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(largs[i], hasThis() ? (i-1) : i); } if (variant == 3) { - gcal = new GregorianCalendar((int32_t)largs[0], (int32_t)largs[1], + tmp = new GregorianCalendar((int32_t)largs[0], (int32_t)largs[1], (int32_t)largs[2], status); } else if (variant == 5) { - gcal = new GregorianCalendar((int32_t)largs[0], (int32_t)largs[1], + tmp = new GregorianCalendar((int32_t)largs[0], (int32_t)largs[1], (int32_t)largs[2], (int32_t)largs[3], (int32_t)largs[4], status); } else if (variant == 6) { - gcal = new GregorianCalendar((int32_t)largs[0], (int32_t)largs[1], + tmp = new GregorianCalendar((int32_t)largs[0], (int32_t)largs[1], (int32_t)largs[2], (int32_t)largs[3], (int32_t)largs[4], (int32_t)largs[5], status); } else { ZEND_UNREACHABLE(); } - if (!set_gregorian_calendar_time_zone(gcal, status)) { - delete gcal; + gcal = std::unique_ptr(tmp); + + if (!set_gregorian_calendar_time_zone(gcal.get(), status)) { if (!is_constructor) { zval_ptr_dtor(return_value); RETVAL_NULL(); @@ -205,36 +204,34 @@ static void _php_intlgregcal_constructor_body( } } - co->ucal = gcal; + co->ucal = gcal.release(); } 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, /* is_constructor */ 0, NULL, NULL); + _php_intlgregcal_constructor_body(INTERNAL_FUNCTION_PARAM_PASSTHRU, /* is_constructor */ false); } U_CFUNC PHP_METHOD(IntlGregorianCalendar, __construct) { - zend_error_handling error_handling; - bool error_handling_replaced = 0; + const bool old_use_exception = INTL_G(use_exceptions); + const zend_long old_error_level = INTL_G(error_level); + INTL_G(use_exceptions) = true; + INTL_G(error_level) = 0; return_value = ZEND_THIS; - _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); - } + _php_intlgregcal_constructor_body(INTERNAL_FUNCTION_PARAM_PASSTHRU, /* is_constructor */ true); + INTL_G(use_exceptions) = old_use_exception; + INTL_G(error_level) = old_error_level; } U_CFUNC PHP_METHOD(IntlGregorianCalendar, createFromDate) { zend_long year, month, day; UErrorCode status = U_ZERO_ERROR; - zend_error_handling error_handling; Calendar_object *co; - GregorianCalendar *gcal; + std::unique_ptr gcal; intl_error_reset(NULL); @@ -248,20 +245,22 @@ U_CFUNC PHP_METHOD(IntlGregorianCalendar, createFromDate) ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(month, 2); ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(day, 3); - zend_replace_error_handling(EH_THROW, IntlException_ce_ptr, &error_handling); + const bool old_use_exception = INTL_G(use_exceptions); + const zend_long old_error_level = INTL_G(error_level); - gcal = new GregorianCalendar((int32_t) year, (int32_t) month, (int32_t) day, status); - if (!set_gregorian_calendar_time_zone(gcal, status)) { - delete gcal; + gcal = std::unique_ptr(new GregorianCalendar((int32_t) year, (int32_t) month, (int32_t) day, status)); + if (!set_gregorian_calendar_time_zone(gcal.get(), status)) { + ZEND_ASSERT(EG(exception)); goto cleanup; } object_init_ex(return_value, GregorianCalendar_ce_ptr); co = Z_INTL_CALENDAR_P(return_value); - co->ucal = gcal; + co->ucal = gcal.release(); cleanup: - zend_restore_error_handling(&error_handling); + INTL_G(use_exceptions) = old_use_exception; + INTL_G(error_level) = old_error_level; } U_CFUNC PHP_METHOD(IntlGregorianCalendar, createFromDateTime) @@ -269,9 +268,8 @@ U_CFUNC PHP_METHOD(IntlGregorianCalendar, createFromDateTime) zend_long year, month, day, hour, minute, second; bool second_is_null = 1; UErrorCode status = U_ZERO_ERROR; - zend_error_handling error_handling; Calendar_object *co; - GregorianCalendar *gcal; + GregorianCalendar *tmp; intl_error_reset(NULL); @@ -291,25 +289,28 @@ U_CFUNC PHP_METHOD(IntlGregorianCalendar, createFromDateTime) ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(hour, 4); ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(minute, 5); - zend_replace_error_handling(EH_THROW, IntlException_ce_ptr, &error_handling); - if (second_is_null) { - gcal = new GregorianCalendar((int32_t) year, (int32_t) month, (int32_t) day, (int32_t) hour, (int32_t) minute, status); + tmp = new GregorianCalendar((int32_t) year, (int32_t) month, (int32_t) day, (int32_t) hour, (int32_t) minute, status); } else { ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(second, 6); - gcal = new GregorianCalendar((int32_t) year, (int32_t) month, (int32_t) day, (int32_t) hour, (int32_t) minute, (int32_t) second, status); + tmp = new GregorianCalendar((int32_t) year, (int32_t) month, (int32_t) day, (int32_t) hour, (int32_t) minute, (int32_t) second, status); } - if (!set_gregorian_calendar_time_zone(gcal, status)) { - delete gcal; + auto gcal = std::unique_ptr(tmp); + const bool old_use_exception = INTL_G(use_exceptions); + const zend_long old_error_level = INTL_G(error_level); + if (!set_gregorian_calendar_time_zone(gcal.get(), status)) { + ZEND_ASSERT(EG(exception)); goto cleanup; } object_init_ex(return_value, GregorianCalendar_ce_ptr); co = Z_INTL_CALENDAR_P(return_value); - co->ucal = gcal; + // TODO: trying to get passed the ownership change step + co->ucal = gcal.release(); cleanup: - zend_restore_error_handling(&error_handling); + INTL_G(use_exceptions) = old_use_exception; + INTL_G(error_level) = old_error_level; } U_CFUNC PHP_FUNCTION(intlgregcal_set_gregorian_change) @@ -326,8 +327,7 @@ U_CFUNC PHP_FUNCTION(intlgregcal_set_gregorian_change) CALENDAR_METHOD_FETCH_OBJECT; fetch_greg(co)->setGregorianChange(date, CALENDAR_ERROR_CODE(co)); - INTL_METHOD_CHECK_STATUS(co, "intlgregcal_set_gregorian_change: error " - "calling ICU method"); + INTL_METHOD_CHECK_STATUS(co, "error calling ICU method"); RETURN_TRUE; } diff --git a/ext/intl/collator/collator_class.h b/ext/intl/collator/collator_class.h index 5c69c2e5aff..311ab5623db 100644 --- a/ext/intl/collator/collator_class.h +++ b/ext/intl/collator/collator_class.h @@ -66,7 +66,7 @@ extern zend_class_entry *Collator_ce_ptr; intl_error_set_code( NULL, COLLATOR_ERROR_CODE( co ) ); \ if( U_FAILURE( COLLATOR_ERROR_CODE( co ) ) ) \ { \ - intl_errors_set_custom_msg( COLLATOR_ERROR_P( co ), msg, 0 ); \ + intl_errors_set_custom_msg( COLLATOR_ERROR_P( co ), msg); \ RETURN_FALSE; \ } \ diff --git a/ext/intl/collator/collator_compare.c b/ext/intl/collator/collator_compare.c index f71d57f74f8..bafaf166ac7 100644 --- a/ext/intl/collator/collator_compare.c +++ b/ext/intl/collator/collator_compare.c @@ -50,8 +50,7 @@ PHP_FUNCTION( collator_compare ) if (!co || !co->ucoll) { intl_error_set_code( NULL, COLLATOR_ERROR_CODE( co ) ); - intl_errors_set_custom_msg( COLLATOR_ERROR_P( co ), - "Object not initialized", 0 ); + intl_errors_set_custom_msg(COLLATOR_ERROR_P( co ), "Object not initialized"); zend_throw_error(NULL, "Object not initialized"); RETURN_THROWS(); @@ -70,8 +69,7 @@ PHP_FUNCTION( collator_compare ) intl_error_set_code( NULL, COLLATOR_ERROR_CODE( co ) ); /* Set error messages. */ - intl_errors_set_custom_msg( COLLATOR_ERROR_P( co ), - "Error converting first argument to UTF-16", 0 ); + intl_errors_set_custom_msg( COLLATOR_ERROR_P( co ), "Error converting first argument to UTF-16"); if (ustr1) { efree( ustr1 ); } @@ -86,8 +84,7 @@ PHP_FUNCTION( collator_compare ) intl_error_set_code( NULL, COLLATOR_ERROR_CODE( co ) ); /* Set error messages. */ - intl_errors_set_custom_msg( COLLATOR_ERROR_P( co ), - "Error converting second argument to UTF-16", 0 ); + intl_errors_set_custom_msg( COLLATOR_ERROR_P( co ), "Error converting second argument to UTF-16"); if (ustr1) { efree( ustr1 ); } diff --git a/ext/intl/collator/collator_create.c b/ext/intl/collator/collator_create.c index 88dacc1c1db..5e6b0dee9ce 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, zend_error_handling *error_handling, bool *error_handling_replaced) +static int collator_ctor(INTERNAL_FUNCTION_PARAMETERS) { char* locale; size_t locale_len = 0; @@ -35,11 +35,6 @@ static int collator_ctor(INTERNAL_FUNCTION_PARAMETERS, zend_error_handling *erro Z_PARAM_STRING(locale, 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; - } - INTL_CHECK_LOCALE_LEN_OR_FAILURE(locale_len); COLLATOR_METHOD_FETCH_OBJECT; @@ -49,7 +44,7 @@ static int collator_ctor(INTERNAL_FUNCTION_PARAMETERS, zend_error_handling *erro /* Open ICU collator. */ co->ucoll = ucol_open( locale, COLLATOR_ERROR_CODE_P( co ) ); - INTL_CTOR_CHECK_STATUS(co, "collator_create: unable to open ICU collator"); + INTL_CTOR_CHECK_STATUS(co, "unable to open ICU collator"); return SUCCESS; } /* }}} */ @@ -58,7 +53,7 @@ static int collator_ctor(INTERNAL_FUNCTION_PARAMETERS, zend_error_handling *erro PHP_FUNCTION( collator_create ) { object_init_ex( return_value, Collator_ce_ptr ); - if (collator_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, NULL, NULL) == FAILURE) { + if (collator_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU) == FAILURE) { zval_ptr_dtor(return_value); RETURN_NULL(); } @@ -68,17 +63,16 @@ PHP_FUNCTION( collator_create ) /* {{{ Collator object constructor. */ PHP_METHOD( Collator, __construct ) { - zend_error_handling error_handling; - bool error_handling_replaced = 0; + const bool old_use_exception = INTL_G(use_exceptions); + const zend_long old_error_level = INTL_G(error_level); + INTL_G(use_exceptions) = true; + INTL_G(error_level) = 0; return_value = ZEND_THIS; - 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); - } - } - if (error_handling_replaced) { - zend_restore_error_handling(&error_handling); + if (collator_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU) == FAILURE) { + ZEND_ASSERT(EG(exception)); } + INTL_G(use_exceptions) = old_use_exception; + INTL_G(error_level) = old_error_level; } /* }}} */ diff --git a/ext/intl/collator/collator_locale.c b/ext/intl/collator/collator_locale.c index e1cdcdf2a60..a7aafa74c26 100644 --- a/ext/intl/collator/collator_locale.c +++ b/ext/intl/collator/collator_locale.c @@ -43,8 +43,7 @@ PHP_FUNCTION( collator_get_locale ) if (!co || !co->ucoll) { intl_error_set_code( NULL, COLLATOR_ERROR_CODE( co ) ); - intl_errors_set_custom_msg( COLLATOR_ERROR_P( co ), - "Object not initialized", 0 ); + intl_errors_set_custom_msg( COLLATOR_ERROR_P( co ), "Object not initialized"); zend_throw_error(NULL, "Object not initialized"); RETURN_THROWS(); diff --git a/ext/intl/collator/collator_sort.c b/ext/intl/collator/collator_sort.c index ee68a21c989..99b75aa0ef2 100644 --- a/ext/intl/collator/collator_sort.c +++ b/ext/intl/collator/collator_sort.c @@ -359,8 +359,7 @@ PHP_FUNCTION( collator_sort_with_sort_keys ) if (!co || !co->ucoll) { intl_error_set_code( NULL, COLLATOR_ERROR_CODE( co ) ); - intl_errors_set_custom_msg( COLLATOR_ERROR_P( co ), - "Object not initialized", 0 ); + intl_errors_set_custom_msg( COLLATOR_ERROR_P( co ), "Object not initialized"); zend_throw_error(NULL, "Object not initialized"); RETURN_THROWS(); @@ -393,7 +392,7 @@ PHP_FUNCTION( collator_sort_with_sort_keys ) if( U_FAILURE( COLLATOR_ERROR_CODE( co ) ) ) { intl_error_set_code( NULL, COLLATOR_ERROR_CODE( co ) ); - intl_errors_set_custom_msg( COLLATOR_ERROR_P( co ), "Sort with sort keys failed", 0 ); + intl_errors_set_custom_msg( COLLATOR_ERROR_P( co ), "Sort with sort keys failed"); if( utf16_buf ) efree( utf16_buf ); @@ -516,8 +515,7 @@ PHP_FUNCTION( collator_get_sort_key ) if (!co || !co->ucoll) { intl_error_set_code( NULL, COLLATOR_ERROR_CODE( co ) ); - intl_errors_set_custom_msg( COLLATOR_ERROR_P( co ), - "Object not initialized", 0 ); + intl_errors_set_custom_msg( COLLATOR_ERROR_P( co ), "Object not initialized"); zend_throw_error(NULL, "Object not initialized"); RETURN_THROWS(); @@ -536,8 +534,7 @@ PHP_FUNCTION( collator_get_sort_key ) intl_error_set_code( NULL, COLLATOR_ERROR_CODE( co ) ); /* Set error messages. */ - intl_errors_set_custom_msg( COLLATOR_ERROR_P( co ), - "Error converting first argument to UTF-16", 0 ); + intl_errors_set_custom_msg( COLLATOR_ERROR_P( co ), "Error converting first argument to UTF-16"); efree( ustr ); RETURN_FALSE; } @@ -553,6 +550,7 @@ PHP_FUNCTION( collator_get_sort_key ) key_len = ucol_getSortKey(co->ucoll, ustr, ustr_len, (uint8_t*)ZSTR_VAL(key_str), key_len); efree( ustr ); if(!key_len) { + zend_string_efree(key_str); RETURN_FALSE; } ZSTR_LEN(key_str) = key_len - 1; diff --git a/ext/intl/common/common_date.cpp b/ext/intl/common/common_date.cpp index e27a67ec55a..f2ca077554b 100644 --- a/ext/intl/common/common_date.cpp +++ b/ext/intl/common/common_date.cpp @@ -30,11 +30,9 @@ using icu::UnicodeString; /* {{{ timezone_convert_datetimezone * The timezone in DateTime and DateTimeZone is not unified. */ -U_CFUNC TimeZone *timezone_convert_datetimezone(int type, - void *object, - int is_datetime, - intl_error *outside_error, - const char *func) +U_CFUNC TimeZone *timezone_convert_datetimezone( + int type, void *object, bool is_datetime, + intl_error *outside_error) { char *id = NULL, offset_id[] = "GMT+00:00"; @@ -58,11 +56,8 @@ U_CFUNC TimeZone *timezone_convert_datetimezone(int type, minutes *= minutes > 0 ? 1 : -1; if (offset_mins <= -24 * 60 || offset_mins >= 24 * 60) { - spprintf(&message, 0, "%s: object has an time zone offset " - "that's too large", func); intl_errors_set(outside_error, U_ILLEGAL_ARGUMENT_ERROR, - message, 1); - efree(message); + "object has an time zone offset that's too large"); return NULL; } @@ -82,10 +77,9 @@ U_CFUNC TimeZone *timezone_convert_datetimezone(int type, UnicodeString s = UnicodeString(id, id_len, US_INV); timeZone = TimeZone::createTimeZone(s); if (*timeZone == TimeZone::getUnknown()) { - spprintf(&message, 0, "%s: time zone id '%s' " - "extracted from ext/date DateTimeZone not recognized", func, id); - intl_errors_set(outside_error, U_ILLEGAL_ARGUMENT_ERROR, - message, 1); + spprintf(&message, 0, "time zone id '%s' " + "extracted from ext/date DateTimeZone not recognized", id); + intl_errors_set(outside_error, U_ILLEGAL_ARGUMENT_ERROR, message); efree(message); delete timeZone; return NULL; @@ -95,7 +89,7 @@ U_CFUNC TimeZone *timezone_convert_datetimezone(int type, /* }}} */ U_CFUNC zend_result intl_datetime_decompose(zend_object *obj, double *millis, TimeZone **tz, - intl_error *err, const char *func) + intl_error *err) { char *message; php_date_obj *datetime = php_date_obj_from_obj(obj); @@ -125,8 +119,8 @@ U_CFUNC zend_result intl_datetime_decompose(zend_object *obj, double *millis, Ti // TODO: Remove this when DateTimeInterface::getTimestamp() no longer has a tentative return type if (Z_TYPE(retval) != IS_LONG) { zval_ptr_dtor(&retval); - spprintf(&message, 0, "%s: %s::getTimestamp() did not return an int", func, ZSTR_VAL(obj->ce->name)); - intl_errors_set(err, U_INTERNAL_PROGRAM_ERROR, message, 1); + spprintf(&message, 0, "%s::getTimestamp() did not return an int", ZSTR_VAL(obj->ce->name)); + intl_errors_set(err, U_INTERNAL_PROGRAM_ERROR, message); efree(message); return FAILURE; } @@ -136,10 +130,9 @@ U_CFUNC zend_result intl_datetime_decompose(zend_object *obj, double *millis, Ti if (tz) { if (!datetime->time) { - spprintf(&message, 0, "%s: the %s object is not properly " - "initialized", func, ZSTR_VAL(obj->ce->name)); - intl_errors_set(err, U_ILLEGAL_ARGUMENT_ERROR, - message, 1); + spprintf(&message, 0, "the %s object is not properly " + "initialized", ZSTR_VAL(obj->ce->name)); + intl_errors_set(err, U_ILLEGAL_ARGUMENT_ERROR, message); efree(message); return FAILURE; } @@ -147,13 +140,10 @@ U_CFUNC zend_result intl_datetime_decompose(zend_object *obj, double *millis, Ti *tz = TimeZone::getGMT()->clone(); } else { *tz = timezone_convert_datetimezone(datetime->time->zone_type, - datetime, 1, NULL, func); + datetime, 1, NULL); if (*tz == NULL) { - spprintf(&message, 0, "%s: could not convert DateTime's " - "time zone", func); intl_errors_set(err, U_ILLEGAL_ARGUMENT_ERROR, - message, 1); - efree(message); + "could not convert DateTime's time zone"); return FAILURE; } } @@ -162,12 +152,11 @@ U_CFUNC zend_result intl_datetime_decompose(zend_object *obj, double *millis, Ti return SUCCESS; } -U_CFUNC double intl_zval_to_millis(zval *z, intl_error *err, const char *func) +U_CFUNC double intl_zval_to_millis(zval *z, intl_error *err) { double rv = ZEND_NAN; zend_long lv; int type; - char *message; if (err && U_FAILURE(err->code)) { return ZEND_NAN; @@ -182,11 +171,12 @@ try_again: } else if (type == IS_LONG) { rv = U_MILLIS_PER_SECOND * (double)lv; } else { - spprintf(&message, 0, "%s: string '%s' is not numeric, " - "which would be required for it to be a valid date", func, + char *message; + spprintf(&message, 0, "string '%s' is not numeric, " + "which would be required for it to be a valid date", Z_STRVAL_P(z)); intl_errors_set(err, U_ILLEGAL_ARGUMENT_ERROR, - message, 1); + message); efree(message); } break; @@ -198,42 +188,32 @@ try_again: break; case IS_OBJECT: if (instanceof_function(Z_OBJCE_P(z), php_date_get_interface_ce())) { - intl_datetime_decompose(Z_OBJ_P(z), &rv, nullptr, err, func); + intl_datetime_decompose(Z_OBJ_P(z), &rv, nullptr, err); } else if (instanceof_function(Z_OBJCE_P(z), Calendar_ce_ptr)) { Calendar_object *co = Z_INTL_CALENDAR_P(z); if (co->ucal == NULL) { - spprintf(&message, 0, "%s: IntlCalendar object is not properly " - "constructed", func); intl_errors_set(err, U_ILLEGAL_ARGUMENT_ERROR, - message, 1); - efree(message); + "IntlCalendar object is not properly constructed"); } else { UErrorCode status = UErrorCode(); rv = (double)co->ucal->getTime(status); if (U_FAILURE(status)) { - spprintf(&message, 0, "%s: call to internal " - "Calendar::getTime() has failed", func); - intl_errors_set(err, status, message, 1); - efree(message); + intl_errors_set(err, status, "call to internal Calendar::getTime() has failed"); } } } else { /* TODO: try with cast(), get() to obtain a number */ - spprintf(&message, 0, "%s: invalid object type for date/time " - "(only IntlCalendar and DateTimeInterface permitted)", func); intl_errors_set(err, U_ILLEGAL_ARGUMENT_ERROR, - message, 1); - efree(message); + "invalid object type for date/time " + "(only IntlCalendar and DateTimeInterface permitted)"); } break; case IS_REFERENCE: z = Z_REFVAL_P(z); goto try_again; default: - spprintf(&message, 0, "%s: invalid PHP type for date", func); intl_errors_set(err, U_ILLEGAL_ARGUMENT_ERROR, - message, 1); - efree(message); + "invalid PHP type for date"); break; } diff --git a/ext/intl/common/common_date.h b/ext/intl/common/common_date.h index e9fac3a02bd..ef007c8eee6 100644 --- a/ext/intl/common/common_date.h +++ b/ext/intl/common/common_date.h @@ -28,11 +28,11 @@ U_CDECL_END using icu::TimeZone; -U_CFUNC TimeZone *timezone_convert_datetimezone(int type, void *object, int is_datetime, intl_error *outside_error, const char *func); -U_CFUNC zend_result intl_datetime_decompose(zend_object *obj, double *millis, TimeZone **tz, intl_error *err, const char *func); +U_CFUNC TimeZone *timezone_convert_datetimezone(int type, void *object, bool is_datetime, intl_error *outside_error); +U_CFUNC zend_result intl_datetime_decompose(zend_object *obj, double *millis, TimeZone **tz, intl_error *err); #endif -U_CFUNC double intl_zval_to_millis(zval *z, intl_error *err, const char *func); +U_CFUNC double intl_zval_to_millis(zval *z, intl_error *err); #endif /* COMMON_DATE_H */ diff --git a/ext/intl/common/common_enum.cpp b/ext/intl/common/common_enum.cpp index 4585a60f077..c2ab946f858 100644 --- a/ext/intl/common/common_enum.cpp +++ b/ext/intl/common/common_enum.cpp @@ -74,8 +74,7 @@ static void string_enum_current_move_forward(zend_object_iterator *iter) intl_error_set_code(NULL, INTLITERATOR_ERROR_CODE(ii)); if (U_FAILURE(INTLITERATOR_ERROR_CODE(ii))) { - intl_errors_set_custom_msg(INTL_DATA_ERROR_P(ii), - "Error fetching next iteration element", 0); + intl_errors_set_custom_msg(INTL_DATA_ERROR_P(ii), "Error fetching next iteration element"); } else if (result) { ZVAL_STRINGL(&zoi_iter->current, result, result_length); } //else we've reached the end of the enum, nothing more is required @@ -105,8 +104,7 @@ static void string_enum_rewind(zend_object_iterator *iter) intl_error_set_code(NULL, INTLITERATOR_ERROR_CODE(ii)); if (U_FAILURE(INTLITERATOR_ERROR_CODE(ii))) { - intl_errors_set_custom_msg(INTL_DATA_ERROR_P(ii), - "Error resetting enumeration", 0); + intl_errors_set_custom_msg(INTL_DATA_ERROR_P(ii), "Error resetting enumeration"); } else { iter->funcs->move_forward(iter); } @@ -268,7 +266,7 @@ PHP_METHOD(IntlIterator, rewind) ii->iterator->funcs->rewind(ii->iterator); } else { intl_errors_set(INTLITERATOR_ERROR_P(ii), U_UNSUPPORTED_ERROR, - "IntlIterator::rewind: rewind not supported", 0); + "rewind not supported"); } } diff --git a/ext/intl/config.m4 b/ext/intl/config.m4 index 20adc3a4ce3..c4c3c9b1d4c 100644 --- a/ext/intl/config.m4 +++ b/ext/intl/config.m4 @@ -33,21 +33,9 @@ if test "$PHP_INTL" != "no"; then formatter/formatter_parse.c grapheme/grapheme_string.c grapheme/grapheme_util.c - idn/idn.c intl_convert.c intl_error.c - locale/locale_class.c - locale/locale_methods.c - locale/locale.c listformatter/listformatter_class.c - msgformat/msgformat_attr.c - msgformat/msgformat_class.c - msgformat/msgformat_data.c - msgformat/msgformat_format.c - msgformat/msgformat_parse.c - msgformat/msgformat.c - normalizer/normalizer_class.c - normalizer/normalizer_normalize.c php_intl.c resourcebundle/resourcebundle_class.c resourcebundle/resourcebundle_iterator.c @@ -57,7 +45,6 @@ if test "$PHP_INTL" != "no"; then spoofchecker/spoofchecker_main.c transliterator/transliterator_class.c transliterator/transliterator_methods.c - uchar/uchar.c ]), [$ext_shared],, [$INTL_COMMON_FLAGS], @@ -78,12 +65,25 @@ if test "$PHP_INTL" != "no"; then calendar/calendar_class.cpp \ calendar/calendar_methods.cpp \ calendar/gregoriancalendar_methods.cpp \ + msgformat/msgformat_attr.cpp \ + msgformat/msgformat_class.cpp \ + msgformat/msgformat_data.cpp \ + msgformat/msgformat_format.cpp \ + msgformat/msgformat_parse.cpp \ + msgformat/msgformat.cpp \ + normalizer/normalizer_class.cpp \ + normalizer/normalizer_normalize.cpp \ breakiterator/breakiterator_class.cpp \ breakiterator/breakiterator_iterators.cpp \ breakiterator/breakiterator_methods.cpp \ breakiterator/rulebasedbreakiterator_methods.cpp \ breakiterator/codepointiterator_internal.cpp \ - breakiterator/codepointiterator_methods.cpp" + breakiterator/codepointiterator_methods.cpp \ + idn/idn.cpp \ + locale/locale_class.cpp \ + locale/locale_methods.cpp \ + locale/locale.cpp \ + uchar/uchar.cpp" PHP_REQUIRE_CXX() diff --git a/ext/intl/config.w32 b/ext/intl/config.w32 index b8161865d25..fb3f0212729 100644 --- a/ext/intl/config.w32 +++ b/ext/intl/config.w32 @@ -43,25 +43,25 @@ if (PHP_INTL != "no") { listformatter_class.c \ ", "intl"); ADD_SOURCES(configure_module_dirname + "/locale", "\ - locale.c \ - locale_class.c \ - locale_methods.c \ + locale.cpp \ + locale_class.cpp \ + locale_methods.cpp \ ", "intl"); ADD_SOURCES(configure_module_dirname + "/msgformat", "\ - msgformat.c \ - msgformat_attr.c \ - msgformat_class.c \ - msgformat_data.c \ - msgformat_format.c \ + msgformat.cpp \ + msgformat_attr.cpp \ + msgformat_class.cpp \ + msgformat_data.cpp \ + msgformat_format.cpp \ msgformat_helpers.cpp \ - msgformat_parse.c \ + msgformat_parse.cpp \ ", "intl"); ADD_SOURCES(configure_module_dirname + "/grapheme", "\ grapheme_string.c grapheme_util.c \ ", "intl"); ADD_SOURCES(configure_module_dirname + "/normalizer", "\ - normalizer_class.c \ - normalizer_normalize.c \ + normalizer_class.cpp \ + normalizer_normalize.cpp \ ", "intl"); ADD_SOURCES(configure_module_dirname + "/dateformat", "\ dateformat.c \ @@ -78,10 +78,10 @@ if (PHP_INTL != "no") { datepatterngenerator_methods.cpp \ ", "intl"); ADD_SOURCES(configure_module_dirname + "/uchar", "\ - uchar.c", + uchar.cpp", "intl"); ADD_SOURCES(configure_module_dirname + "/idn", "\ - idn.c", + idn.cpp", "intl"); ADD_SOURCES(configure_module_dirname + "/resourcebundle", "\ resourcebundle.c \ diff --git a/ext/intl/converter/converter.c b/ext/intl/converter/converter.c index 3aa7a53aa48..759db5e1887 100644 --- a/ext/intl/converter/converter.c +++ b/ext/intl/converter/converter.c @@ -24,6 +24,7 @@ #include "../intl_error.h" #include "../intl_common.h" #include "converter_arginfo.h" +#include "php_intl.h" typedef struct _php_converter_object { UConverter *src, *dest; @@ -42,8 +43,8 @@ static zend_class_entry *php_converter_ce; static zend_object_handlers php_converter_object_handlers; #define CONV_GET(pzv) (Z_INTL_CONVERTER_P((pzv))) -#define THROW_UFAILURE(obj, fname, error) php_converter_throw_failure(obj, error, \ - fname "() returned error " ZEND_LONG_FMT ": %s", (zend_long)error, u_errorName(error)) +#define THROW_UFAILURE(obj, error) php_converter_throw_failure(obj, error, \ + "returned error " ZEND_LONG_FMT ": %s", (zend_long)error, u_errorName(error)) /* {{{ php_converter_throw_failure */ static inline void php_converter_throw_failure(php_converter_object *objval, UErrorCode error, const char *format, ...) { @@ -55,7 +56,7 @@ static inline void php_converter_throw_failure(php_converter_object *objval, UEr vsnprintf(message, sizeof(message), format, vargs); va_end(vargs); - intl_errors_set(err, error, message, 1); + intl_errors_set(err, error, message); } /* }}} */ @@ -90,7 +91,7 @@ static void php_converter_default_callback(zval *return_value, zval *zobj, zend_ */ ucnv_getSubstChars(objval->src, chars, &chars_len, &uerror); if (U_FAILURE(uerror)) { - THROW_UFAILURE(objval, "ucnv_getSubstChars", uerror); + THROW_UFAILURE(objval, uerror); chars[0] = 0x1A; chars[1] = 0; chars_len = 1; @@ -341,7 +342,7 @@ static inline bool php_converter_set_callbacks(php_converter_object *objval, UCo ucnv_setToUCallBack(cnv, (UConverterToUCallback)php_converter_to_u_callback, (const void*)objval, NULL, NULL, &error); if (U_FAILURE(error)) { - THROW_UFAILURE(objval, "ucnv_setToUCallBack", error); + THROW_UFAILURE(objval, error); ret = 0; } @@ -349,7 +350,7 @@ static inline bool php_converter_set_callbacks(php_converter_object *objval, UCo ucnv_setFromUCallBack(cnv, (UConverterFromUCallback)php_converter_from_u_callback, (const void*)objval, NULL, NULL, &error); if (U_FAILURE(error)) { - THROW_UFAILURE(objval, "ucnv_setFromUCallBack", error); + THROW_UFAILURE(objval, error); ret = 0; } return ret; @@ -370,14 +371,17 @@ static bool php_converter_set_encoding(php_converter_object *objval, /* Should never happen */ actual_encoding = "(unknown)"; } - php_error_docref(NULL, E_WARNING, "Ambiguous encoding specified, using %s", actual_encoding); + char *msg; + spprintf(&msg, 0, "Ambiguous encoding specified, using %s", actual_encoding); + intl_error_set(NULL, error, msg); + efree(msg); } else if (U_FAILURE(error)) { if (objval) { - THROW_UFAILURE(objval, "ucnv_open", error); + THROW_UFAILURE(objval, error); } else { char *msg; spprintf(&msg, 0, "Error setting encoding: %d - %s", (int)error, u_errorName(error)); - intl_error_set(NULL, error, msg, 1); + intl_error_set(NULL, error, msg); efree(msg); } return false; @@ -439,7 +443,7 @@ static void php_converter_do_get_encoding(php_converter_object *objval, UConvert name = ucnv_getName(cnv, &objval->error.code); if (U_FAILURE(objval->error.code)) { - THROW_UFAILURE(objval, "ucnv_getName()", objval->error.code); + THROW_UFAILURE(objval, objval->error.code); RETURN_FALSE; } @@ -474,7 +478,7 @@ static void php_converter_do_get_type(php_converter_object *objval, UConverter * t = ucnv_getType(cnv); if (U_FAILURE(objval->error.code)) { - THROW_UFAILURE(objval, "ucnv_getType", objval->error.code); + THROW_UFAILURE(objval, objval->error.code); RETURN_FALSE; } @@ -530,10 +534,23 @@ PHP_METHOD(UConverter, __construct) { Z_PARAM_STRING_OR_NULL(src, src_len) ZEND_PARSE_PARAMETERS_END(); - php_converter_set_encoding(objval, &(objval->src), src, src_len ); - php_converter_set_encoding(objval, &(objval->dest), dest, dest_len); + const bool old_use_exception = INTL_G(use_exceptions); + const zend_long old_error_level = INTL_G(error_level); + INTL_G(use_exceptions) = true; + INTL_G(error_level) = 0; + if (UNEXPECTED(!php_converter_set_encoding(objval, &(objval->src), src, src_len))) { + ZEND_ASSERT(EG(exception)); + goto cleanup; + } + if (UNEXPECTED(!php_converter_set_encoding(objval, &(objval->dest), dest, dest_len))) { + ZEND_ASSERT(EG(exception)); + goto cleanup; + } php_converter_resolve_callback(&objval->to_cache, Z_OBJ_P(ZEND_THIS), ZEND_STRL("toUCallback")); php_converter_resolve_callback(&objval->from_cache, Z_OBJ_P(ZEND_THIS), ZEND_STRL("fromUCallback")); +cleanup: + INTL_G(use_exceptions) = old_use_exception; + INTL_G(error_level) = old_error_level; } /* }}} */ @@ -554,7 +571,7 @@ PHP_METHOD(UConverter, setSubstChars) { UErrorCode error = U_ZERO_ERROR; ucnv_setSubstChars(objval->src, chars, chars_len, &error); if (U_FAILURE(error)) { - THROW_UFAILURE(objval, "ucnv_setSubstChars", error); + THROW_UFAILURE(objval, error); ret = 0; } } else { @@ -566,7 +583,7 @@ PHP_METHOD(UConverter, setSubstChars) { UErrorCode error = U_ZERO_ERROR; ucnv_setSubstChars(objval->dest, chars, chars_len, &error); if (U_FAILURE(error)) { - THROW_UFAILURE(objval, "ucnv_setSubstChars", error); + THROW_UFAILURE(objval, error); ret = 0; } } else { @@ -597,7 +614,7 @@ PHP_METHOD(UConverter, getSubstChars) { */ ucnv_getSubstChars(objval->src, chars, &chars_len, &error); if (U_FAILURE(error)) { - THROW_UFAILURE(objval, "ucnv_getSubstChars", error); + THROW_UFAILURE(objval, error); RETURN_FALSE; } @@ -624,7 +641,7 @@ static zend_string* php_converter_do_convert(UConverter *dest_cnv, /* Get necessary buffer size first */ temp_len = 1 + ucnv_toUChars(src_cnv, NULL, 0, src, src_len, &error); if (U_FAILURE(error) && error != U_BUFFER_OVERFLOW_ERROR) { - THROW_UFAILURE(objval, "ucnv_toUChars", error); + THROW_UFAILURE(objval, error); return NULL; } temp = safe_emalloc(sizeof(UChar), temp_len, sizeof(UChar)); @@ -633,7 +650,7 @@ static zend_string* php_converter_do_convert(UConverter *dest_cnv, error = U_ZERO_ERROR; temp_len = ucnv_toUChars(src_cnv, temp, temp_len, src, src_len, &error); if (U_FAILURE(error)) { - THROW_UFAILURE(objval, "ucnv_toUChars", error); + THROW_UFAILURE(objval, error); efree(temp); return NULL; } @@ -642,7 +659,7 @@ static zend_string* php_converter_do_convert(UConverter *dest_cnv, /* Get necessary output buffer size */ ret_len = ucnv_fromUChars(dest_cnv, NULL, 0, temp, temp_len, &error); if (U_FAILURE(error) && error != U_BUFFER_OVERFLOW_ERROR) { - THROW_UFAILURE(objval, "ucnv_fromUChars", error); + THROW_UFAILURE(objval, error); efree(temp); return NULL; } @@ -654,7 +671,7 @@ static zend_string* php_converter_do_convert(UConverter *dest_cnv, ZSTR_LEN(ret) = ucnv_fromUChars(dest_cnv, ZSTR_VAL(ret), ret_len+1, temp, temp_len, &error); efree(temp); if (U_FAILURE(error)) { - THROW_UFAILURE(objval, "ucnv_fromUChars", error); + THROW_UFAILURE(objval, error); zend_string_efree(ret); return NULL; } @@ -758,7 +775,7 @@ PHP_METHOD(UConverter, transcode) { } if (U_FAILURE(error)) { - THROW_UFAILURE(NULL, "transcode", error); + THROW_UFAILURE(NULL, error); RETVAL_FALSE; } } else { @@ -831,7 +848,7 @@ PHP_METHOD(UConverter, getAliases) { count = ucnv_countAliases(name, &error); if (U_FAILURE(error)) { - THROW_UFAILURE(NULL, "ucnv_countAliases", error); + THROW_UFAILURE(NULL, error); RETURN_FALSE; } @@ -843,7 +860,7 @@ PHP_METHOD(UConverter, getAliases) { error = U_ZERO_ERROR; alias = ucnv_getAlias(name, i, &error); if (U_FAILURE(error)) { - THROW_UFAILURE(NULL, "ucnv_getAlias", error); + THROW_UFAILURE(NULL, error); zend_array_destroy(Z_ARR_P(return_value)); RETURN_NULL(); } @@ -866,7 +883,7 @@ PHP_METHOD(UConverter, getStandards) { UErrorCode error = U_ZERO_ERROR; const char *name = ucnv_getStandard(i, &error); if (U_FAILURE(error)) { - THROW_UFAILURE(NULL, "ucnv_getStandard", error); + THROW_UFAILURE(NULL, error); zend_array_destroy(Z_ARR_P(return_value)); RETURN_NULL(); } diff --git a/ext/intl/dateformat/dateformat.stub.php b/ext/intl/dateformat/dateformat.stub.php index 7582af2717f..89ebc5f61c0 100644 --- a/ext/intl/dateformat/dateformat.stub.php +++ b/ext/intl/dateformat/dateformat.stub.php @@ -32,20 +32,18 @@ class IntlDateFormatter public const int TRADITIONAL = UNKNOWN; /** - * @param IntlTimeZone|DateTimeZone|string|null $timezone * @param IntlCalendar|int|null $calendar */ public function __construct( ?string $locale, int $dateType = IntlDateFormatter::FULL, int $timeType = IntlDateFormatter::FULL, - $timezone = null, + IntlTimeZone|DateTimeZone|string|null $timezone = null, $calendar = null, ?string $pattern = null ) {} /** - * @param IntlTimeZone|DateTimeZone|string|null $timezone * @tentative-return-type * @alias datefmt_create */ @@ -53,7 +51,7 @@ class IntlDateFormatter ?string $locale, int $dateType = IntlDateFormatter::FULL, int $timeType = IntlDateFormatter::FULL, - $timezone = null, + IntlTimeZone|DateTimeZone|string|null $timezone = null, IntlCalendar|int|null $calendar = null, ?string $pattern = null ): ?IntlDateFormatter {} @@ -101,11 +99,9 @@ class IntlDateFormatter public function getTimeZone(): IntlTimeZone|false {} /** - * @param IntlTimeZone|DateTimeZone|string|null $timezone * @tentative-return-type - * @alias datefmt_set_timezone */ - public function setTimeZone($timezone): bool {} + public function setTimeZone(IntlTimeZone|DateTimeZone|string|null $timezone): bool {} /** * @tentative-return-type diff --git a/ext/intl/dateformat/dateformat_arginfo.h b/ext/intl/dateformat/dateformat_arginfo.h index b57cb79468f..d6d0306506f 100644 --- a/ext/intl/dateformat/dateformat_arginfo.h +++ b/ext/intl/dateformat/dateformat_arginfo.h @@ -1,11 +1,11 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 56b66b1b51220ddbff698ec4c9a6ae60f3e0bfb0 */ + * Stub hash: 160d05ec65c45b66b13eaecbef20b3c59bfb33d1 */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_IntlDateFormatter___construct, 0, 0, 1) ZEND_ARG_TYPE_INFO(0, locale, IS_STRING, 1) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, dateType, IS_LONG, 0, "IntlDateFormatter::FULL") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, timeType, IS_LONG, 0, "IntlDateFormatter::FULL") - ZEND_ARG_INFO_WITH_DEFAULT_VALUE(0, timezone, "null") + ZEND_ARG_OBJ_TYPE_MASK(0, timezone, IntlTimeZone|DateTimeZone, MAY_BE_STRING|MAY_BE_NULL, "null") ZEND_ARG_INFO_WITH_DEFAULT_VALUE(0, calendar, "null") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, pattern, IS_STRING, 1, "null") ZEND_END_ARG_INFO() @@ -14,7 +14,7 @@ ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_INFO_EX(arginfo_class_IntlDateFormatter ZEND_ARG_TYPE_INFO(0, locale, IS_STRING, 1) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, dateType, IS_LONG, 0, "IntlDateFormatter::FULL") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, timeType, IS_LONG, 0, "IntlDateFormatter::FULL") - ZEND_ARG_INFO_WITH_DEFAULT_VALUE(0, timezone, "null") + ZEND_ARG_OBJ_TYPE_MASK(0, timezone, IntlTimeZone|DateTimeZone, MAY_BE_STRING|MAY_BE_NULL, "null") ZEND_ARG_OBJ_TYPE_MASK(0, calendar, IntlCalendar, MAY_BE_LONG|MAY_BE_NULL, "null") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, pattern, IS_STRING, 1, "null") ZEND_END_ARG_INFO() @@ -40,7 +40,7 @@ ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_IntlDateForm ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_IntlDateFormatter_setTimeZone, 0, 1, _IS_BOOL, 0) - ZEND_ARG_INFO(0, timezone) + ZEND_ARG_OBJ_TYPE_MASK(0, timezone, IntlTimeZone|DateTimeZone, MAY_BE_STRING|MAY_BE_NULL, NULL) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_IntlDateFormatter_setPattern, 0, 1, _IS_BOOL, 0) @@ -100,7 +100,7 @@ ZEND_FUNCTION(datefmt_set_calendar); ZEND_FUNCTION(datefmt_get_timezone_id); ZEND_FUNCTION(datefmt_get_calendar_object); ZEND_FUNCTION(datefmt_get_timezone); -ZEND_FUNCTION(datefmt_set_timezone); +ZEND_METHOD(IntlDateFormatter, setTimeZone); ZEND_FUNCTION(datefmt_set_pattern); ZEND_FUNCTION(datefmt_get_pattern); ZEND_FUNCTION(datefmt_get_locale); @@ -124,7 +124,7 @@ static const zend_function_entry class_IntlDateFormatter_methods[] = { ZEND_RAW_FENTRY("getTimeZoneId", zif_datefmt_get_timezone_id, arginfo_class_IntlDateFormatter_getTimeZoneId, ZEND_ACC_PUBLIC, NULL, NULL) ZEND_RAW_FENTRY("getCalendarObject", zif_datefmt_get_calendar_object, arginfo_class_IntlDateFormatter_getCalendarObject, ZEND_ACC_PUBLIC, NULL, NULL) ZEND_RAW_FENTRY("getTimeZone", zif_datefmt_get_timezone, arginfo_class_IntlDateFormatter_getTimeZone, ZEND_ACC_PUBLIC, NULL, NULL) - ZEND_RAW_FENTRY("setTimeZone", zif_datefmt_set_timezone, arginfo_class_IntlDateFormatter_setTimeZone, ZEND_ACC_PUBLIC, NULL, NULL) + ZEND_ME(IntlDateFormatter, setTimeZone, arginfo_class_IntlDateFormatter_setTimeZone, ZEND_ACC_PUBLIC) ZEND_RAW_FENTRY("setPattern", zif_datefmt_set_pattern, arginfo_class_IntlDateFormatter_setPattern, ZEND_ACC_PUBLIC, NULL, NULL) ZEND_RAW_FENTRY("getPattern", zif_datefmt_get_pattern, arginfo_class_IntlDateFormatter_getPattern, ZEND_ACC_PUBLIC, NULL, NULL) ZEND_RAW_FENTRY("getLocale", zif_datefmt_get_locale, arginfo_class_IntlDateFormatter_getLocale, ZEND_ACC_PUBLIC, NULL, NULL) diff --git a/ext/intl/dateformat/dateformat_attrcpp.cpp b/ext/intl/dateformat/dateformat_attrcpp.cpp index 1fb5b514bc6..13dadc9c969 100644 --- a/ext/intl/dateformat/dateformat_attrcpp.cpp +++ b/ext/intl/dateformat/dateformat_attrcpp.cpp @@ -71,8 +71,7 @@ U_CFUNC PHP_FUNCTION(datefmt_get_timezone) TimeZone *tz_clone = tz.clone(); if (UNEXPECTED(tz_clone == NULL)) { intl_errors_set(INTL_DATA_ERROR_P(dfo), U_MEMORY_ALLOCATION_ERROR, - "datefmt_get_timezone: Out of memory when cloning time zone", - 0); + "Out of memory when cloning time zone"); RETURN_FALSE; } @@ -82,21 +81,46 @@ U_CFUNC PHP_FUNCTION(datefmt_get_timezone) /* {{{ Set formatter's timezone. */ U_CFUNC PHP_FUNCTION(datefmt_set_timezone) { - zval *timezone_zv; - TimeZone *timezone; + zend_object *timezone_object = nullptr; + zend_string *timezone_string = nullptr; DATE_FORMAT_METHOD_INIT_VARS; - if ( zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), - "Oz", &object, IntlDateFormatter_ce_ptr, &timezone_zv) == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_START(2, 2) + Z_PARAM_OBJECT_OF_CLASS(object, IntlDateFormatter_ce_ptr) + Z_PARAM_OBJ_OR_STR_OR_NULL(timezone_object, timezone_string) + ZEND_PARSE_PARAMETERS_END(); DATE_FORMAT_METHOD_FETCH_OBJECT; - timezone = timezone_process_timezone_argument(timezone_zv, - INTL_DATA_ERROR_P(dfo), "datefmt_set_timezone"); - if (timezone == NULL) { + TimeZone *timezone = timezone_process_timezone_argument( + timezone_object, timezone_string, INTL_DATA_ERROR_P(dfo)); + if (timezone == nullptr) { + RETURN_FALSE; + } + + fetch_datefmt(dfo)->adoptTimeZone(timezone); + + RETURN_TRUE; +} + +U_CFUNC PHP_METHOD(IntlDateFormatter, setTimeZone) +{ + zend_object *timezone_object = nullptr; + zend_string *timezone_string = nullptr; + + DATE_FORMAT_METHOD_INIT_VARS; + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_OBJ_OR_STR_OR_NULL(timezone_object, timezone_string) + ZEND_PARSE_PARAMETERS_END(); + + object = ZEND_THIS; + DATE_FORMAT_METHOD_FETCH_OBJECT; + + TimeZone *timezone = timezone_process_timezone_argument( + timezone_object, timezone_string, INTL_DATA_ERROR_P(dfo)); + if (timezone == nullptr) { RETURN_FALSE; } @@ -146,8 +170,7 @@ U_CFUNC PHP_FUNCTION(datefmt_get_calendar_object) Calendar *cal_clone = cal->clone(); if (UNEXPECTED(cal_clone == NULL)) { intl_errors_set(INTL_DATA_ERROR_P(dfo), U_MEMORY_ALLOCATION_ERROR, - "datefmt_get_calendar_object: Out of memory when cloning " - "calendar", 0); + "Out of memory when cloning calendar"); RETURN_FALSE; } @@ -187,7 +210,7 @@ U_CFUNC PHP_FUNCTION(datefmt_set_calendar) // must store the requested locale on object creation if (datefmt_process_calendar_arg(calendar_obj, calendar_long, calendar_is_null, locale, - "datefmt_set_calendar", INTL_DATA_ERROR_P(dfo), cal, cal_type, cal_owned) == FAILURE + INTL_DATA_ERROR_P(dfo), cal, cal_type, cal_owned) == FAILURE ) { RETURN_FALSE; } @@ -197,8 +220,7 @@ U_CFUNC PHP_FUNCTION(datefmt_set_calendar) TimeZone *old_timezone = fetch_datefmt(dfo)->getTimeZone().clone(); if (UNEXPECTED(old_timezone == NULL)) { intl_errors_set(INTL_DATA_ERROR_P(dfo), U_MEMORY_ALLOCATION_ERROR, - "datefmt_set_calendar: Out of memory when cloning calendar", - 0); + "Out of memory when cloning calendar"); delete cal; RETURN_FALSE; } @@ -207,8 +229,7 @@ U_CFUNC PHP_FUNCTION(datefmt_set_calendar) cal = cal->clone(); if (UNEXPECTED(cal == NULL)) { intl_errors_set(INTL_DATA_ERROR_P(dfo), U_MEMORY_ALLOCATION_ERROR, - "datefmt_set_calendar: Out of memory when cloning calendar", - 0); + "Out of memory when cloning calendar"); RETURN_FALSE; } } diff --git a/ext/intl/dateformat/dateformat_create.cpp b/ext/intl/dateformat/dateformat_create.cpp index d071c7d9d2e..d2d65bc2673 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, zend_error_handling *error_handling, bool *error_handling_replaced) +static zend_result datefmt_ctor(INTERNAL_FUNCTION_PARAMETERS) { zval *object; char *locale_str; @@ -59,7 +59,8 @@ static zend_result datefmt_ctor(INTERNAL_FUNCTION_PARAMETERS, zend_error_handlin Calendar *cal = NULL; zend_long calendar_type; bool calendar_owned; - zval *timezone_zv = NULL; + zend_object *timezone_object = nullptr; + zend_string *timezone_string = nullptr; TimeZone *timezone = NULL; bool explicit_tz; char* pattern_str = NULL; @@ -76,33 +77,28 @@ static zend_result datefmt_ctor(INTERNAL_FUNCTION_PARAMETERS, zend_error_handlin Z_PARAM_OPTIONAL Z_PARAM_LONG(date_type) Z_PARAM_LONG(time_type) - Z_PARAM_ZVAL(timezone_zv) + Z_PARAM_OBJ_OR_STR_OR_NULL(timezone_object, timezone_string) Z_PARAM_OBJ_OF_CLASS_OR_LONG_OR_NULL(calendar_obj, Calendar_ce_ptr, calendar_long, calendar_is_null) 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) { - intl_errors_set(INTL_DATA_ERROR_P(dfo), U_ILLEGAL_ARGUMENT_ERROR, "datefmt_create: cannot call constructor twice", 0); + intl_errors_set(INTL_DATA_ERROR_P(dfo), U_ILLEGAL_ARGUMENT_ERROR, "cannot call constructor twice"); return FAILURE; } if (!INTL_UDATE_FMT_OK(date_type)) { - intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "datefmt_create: invalid date format style", 0); + intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "invalid date format style"); return FAILURE; } if (!INTL_UDATE_FMT_OK(time_type)) { - intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "datefmt_create: invalid time format style", 0); + intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "invalid time format style"); return FAILURE; } if (date_type == UDAT_PATTERN && time_type != UDAT_PATTERN) { - intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "datefmt_create: time format must be UDAT_PATTERN if date format is UDAT_PATTERN", 0); + intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "time format must be UDAT_PATTERN if date format is UDAT_PATTERN"); return FAILURE; } @@ -118,20 +114,19 @@ static zend_result datefmt_ctor(INTERNAL_FUNCTION_PARAMETERS, zend_error_handlin } /* process calendar */ - if (datefmt_process_calendar_arg(calendar_obj, calendar_long, calendar_is_null, locale, "datefmt_create", + if (datefmt_process_calendar_arg(calendar_obj, calendar_long, calendar_is_null, locale, INTL_DATA_ERROR_P(dfo), cal, calendar_type, calendar_owned) == FAILURE ) { goto error; } /* process timezone */ - explicit_tz = timezone_zv != NULL && Z_TYPE_P(timezone_zv) != IS_NULL; + explicit_tz = timezone_object != nullptr || timezone_string != nullptr; if (explicit_tz || calendar_owned ) { //we have an explicit time zone or a non-object calendar - timezone = timezone_process_timezone_argument(timezone_zv, - INTL_DATA_ERROR_P(dfo), "datefmt_create"); - if (timezone == NULL) { + timezone = timezone_process_timezone_argument(timezone_object, timezone_string, INTL_DATA_ERROR_P(dfo)); + if (timezone == nullptr) { goto error; } } @@ -142,8 +137,8 @@ static zend_result datefmt_ctor(INTERNAL_FUNCTION_PARAMETERS, zend_error_handlin pattern_str, pattern_str_len, &INTL_DATA_ERROR_CODE(dfo)); if (U_FAILURE(INTL_DATA_ERROR_CODE(dfo))) { /* object construction -> only set global error */ - intl_error_set(NULL, INTL_DATA_ERROR_CODE(dfo), "datefmt_create: " - "error converting pattern to UTF-16", 0); + intl_error_set(NULL, INTL_DATA_ERROR_CODE(dfo), + "error converting pattern to UTF-16"); goto error; } } @@ -155,7 +150,7 @@ static zend_result datefmt_ctor(INTERNAL_FUNCTION_PARAMETERS, zend_error_handlin if (pattern_str && pattern_str_len > 0) { udat_applyPattern(DATE_FORMAT_OBJECT(dfo), true, svalue, slength); if (U_FAILURE(INTL_DATA_ERROR_CODE(dfo))) { - intl_error_set(NULL, INTL_DATA_ERROR_CODE(dfo), "datefmt_create: error applying pattern", 0); + intl_error_set(NULL, INTL_DATA_ERROR_CODE(dfo), "error applying pattern"); goto error; } } @@ -173,8 +168,7 @@ static zend_result datefmt_ctor(INTERNAL_FUNCTION_PARAMETERS, zend_error_handlin df->adoptTimeZone(timezone); } } else { - intl_error_set(NULL, INTL_DATA_ERROR_CODE(dfo), "datefmt_create: date " - "formatter creation failed", 0); + intl_error_set(NULL, INTL_DATA_ERROR_CODE(dfo), "date formatter creation failed"); goto error; } @@ -203,7 +197,7 @@ error: U_CFUNC PHP_FUNCTION( datefmt_create ) { object_init_ex( return_value, IntlDateFormatter_ce_ptr ); - if (datefmt_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, NULL, NULL) == FAILURE) { + if (datefmt_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU) == FAILURE) { zval_ptr_dtor(return_value); RETURN_NULL(); } @@ -213,21 +207,18 @@ U_CFUNC PHP_FUNCTION( datefmt_create ) /* {{{ IntlDateFormatter object constructor. */ U_CFUNC PHP_METHOD( IntlDateFormatter, __construct ) { - zend_error_handling error_handling; - bool error_handling_replaced = 0; + const bool old_use_exception = INTL_G(use_exceptions); + const zend_long old_error_level = INTL_G(error_level); + INTL_G(use_exceptions) = true; + INTL_G(error_level) = 0; /* return_value param is being changed, therefore we will always return * NULL here */ return_value = ZEND_THIS; - 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); - } - } - if (error_handling_replaced) { - zend_restore_error_handling(&error_handling); + if (datefmt_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU) == FAILURE) { + ZEND_ASSERT(EG(exception)); } + INTL_G(use_exceptions) = old_use_exception; + INTL_G(error_level) = old_error_level; } /* }}} */ diff --git a/ext/intl/dateformat/dateformat_format.c b/ext/intl/dateformat/dateformat_format.c index f4ef8a40d64..ee3abd052d6 100644 --- a/ext/intl/dateformat/dateformat_format.c +++ b/ext/intl/dateformat/dateformat_format.c @@ -66,17 +66,17 @@ static int32_t internal_get_arr_ele(IntlDateFormatter_object *dfo, if ((ele_value = zend_hash_str_find_deref(hash_arr, key_name, strlen(key_name))) != NULL) { if(Z_TYPE_P(ele_value) != IS_LONG) { - spprintf(&message, 0, "datefmt_format: parameter array contains " + spprintf(&message, 0, "parameter array contains " "a non-integer element for key '%s'", key_name); - intl_errors_set(err, U_ILLEGAL_ARGUMENT_ERROR, message, 1); + intl_errors_set(err, U_ILLEGAL_ARGUMENT_ERROR, message); efree(message); } else { if (Z_LVAL_P(ele_value) > INT32_MAX || Z_LVAL_P(ele_value) < INT32_MIN) { - spprintf(&message, 0, "datefmt_format: value " ZEND_LONG_FMT " is out of " + spprintf(&message, 0, "value " ZEND_LONG_FMT " is out of " "bounds for a 32-bit integer in key '%s'", Z_LVAL_P(ele_value), key_name); - intl_errors_set(err, U_ILLEGAL_ARGUMENT_ERROR, message, 1); + intl_errors_set(err, U_ILLEGAL_ARGUMENT_ERROR, message); efree(message); } else { result = Z_LVAL_P(ele_value); @@ -121,8 +121,7 @@ static UDate internal_get_timestamp(IntlDateFormatter_object *dfo, &INTL_DATA_ERROR_CODE(dfo)); if (INTL_DATA_ERROR_CODE(dfo) != U_ZERO_ERROR) { - intl_errors_set(err, INTL_DATA_ERROR_CODE(dfo), "datefmt_format: " - "error cloning calendar", 0); + intl_errors_set(err, INTL_DATA_ERROR_CODE(dfo), "error cloning calendar"); return 0; } @@ -149,8 +148,6 @@ PHP_FUNCTION(datefmt_format) /* Parse parameters. */ if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Oz", &object, IntlDateFormatter_ce_ptr, &zarg) == FAILURE) { - intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "datefmt_format: unable " - "to parse input params", 0 ); RETURN_THROWS(); } @@ -163,10 +160,9 @@ PHP_FUNCTION(datefmt_format) } timestamp = internal_get_timestamp(dfo, hash_arr); - INTL_METHOD_CHECK_STATUS(dfo, "datefmt_format: date formatting failed") + INTL_METHOD_CHECK_STATUS(dfo, "date formatting failed") } else { - timestamp = intl_zval_to_millis(zarg, INTL_DATA_ERROR_P(dfo), - "datefmt_format"); + timestamp = intl_zval_to_millis(zarg, INTL_DATA_ERROR_P(dfo)); if (U_FAILURE(INTL_DATA_ERROR_CODE(dfo))) { RETURN_FALSE; } diff --git a/ext/intl/dateformat/dateformat_format_object.cpp b/ext/intl/dateformat/dateformat_format_object.cpp index 81490c62fd5..a5113ce4cf9 100644 --- a/ext/intl/dateformat/dateformat_format_object.cpp +++ b/ext/intl/dateformat/dateformat_format_object.cpp @@ -13,6 +13,7 @@ */ #include "../intl_cppshims.h" +#include #include #include @@ -70,10 +71,10 @@ U_CFUNC PHP_FUNCTION(datefmt_format_object) size_t locale_len; bool pattern = false; UDate date; - TimeZone *timeZone = NULL; + std::unique_ptr timeZone; UErrorCode status = U_ZERO_ERROR; - DateFormat *df = NULL; - Calendar *cal = NULL; + std::unique_ptr df; + std::unique_ptr cal; DateFormat::EStyle dateStyle = DateFormat::kDefault, timeStyle = DateFormat::kDefault; @@ -94,8 +95,8 @@ U_CFUNC PHP_FUNCTION(datefmt_format_object) HashTable *ht = Z_ARRVAL_P(format); if (zend_hash_num_elements(ht) != 2) { intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, - "datefmt_format_object: bad format; if array, it must have " - "two elements", 0); + "bad format; if array, it must have " + "two elements"); RETURN_FALSE; } @@ -105,13 +106,13 @@ U_CFUNC PHP_FUNCTION(datefmt_format_object) if (!valid_format(z)) { if (idx == 0) { intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, - "datefmt_format_object: bad format; the date format (first " - "element of the array) is not valid", 0); + "bad format; the date format (first " + "element of the array) is not valid"); } else { ZEND_ASSERT(idx == 1 && "We checked that there are two elements above"); intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, - "datefmt_format_object: bad format; the time format (second " - "element of the array) is not valid", 0); + "bad format; the time format (second " + "element of the array) is not valid"); } RETURN_FALSE; } @@ -127,8 +128,7 @@ U_CFUNC PHP_FUNCTION(datefmt_format_object) } else if (Z_TYPE_P(format) == IS_LONG) { if (!valid_format(format)) { intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, - "datefmt_format_object: the date/time format type is invalid", - 0); + "the date/time format type is invalid"); RETURN_FALSE; } dateStyle = timeStyle = (DateFormat::EStyle)Z_LVAL_P(format); @@ -138,7 +138,7 @@ U_CFUNC PHP_FUNCTION(datefmt_format_object) } if (Z_STRLEN_P(format) == 0) { intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, - "datefmt_format_object: the format is empty", 0); + "the format is empty"); RETURN_FALSE; } pattern = true; @@ -154,72 +154,58 @@ U_CFUNC PHP_FUNCTION(datefmt_format_object) Calendar *obj_cal = calendar_fetch_native_calendar(object); if (obj_cal == NULL) { intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, - "datefmt_format_object: bad IntlCalendar instance: " - "not initialized properly", 0); + "bad IntlCalendar instance: not initialized properly"); RETURN_FALSE; } - timeZone = obj_cal->getTimeZone().clone(); + timeZone = std::unique_ptr(obj_cal->getTimeZone().clone()); date = obj_cal->getTime(status); if (U_FAILURE(status)) { intl_error_set(NULL, status, - "datefmt_format_object: error obtaining instant from " - "IntlCalendar", 0); - RETVAL_FALSE; - goto cleanup; - } - cal = obj_cal->clone(); - } else if (instanceof_function(instance_ce, php_date_get_interface_ce())) { - if (intl_datetime_decompose(object, &date, &timeZone, NULL, - "datefmt_format_object") == FAILURE) { + "error obtaining instant from IntlCalendar"); RETURN_FALSE; } - cal = new GregorianCalendar(Locale::createFromName(locale_str), status); + cal = std::unique_ptr(obj_cal->clone()); + } else if (instanceof_function(instance_ce, php_date_get_interface_ce())) { + TimeZone *tz; + if (intl_datetime_decompose(object, &date, &tz, NULL) == FAILURE) { + RETURN_FALSE; + } + timeZone = std::unique_ptr(tz); + cal = std::unique_ptr(new GregorianCalendar(Locale::createFromName(locale_str), status)); if (U_FAILURE(status)) { - intl_error_set(NULL, status, - "datefmt_format_object: could not create GregorianCalendar", - 0); - RETVAL_FALSE; - goto cleanup; + intl_error_set(NULL, status, "could not create GregorianCalendar"); + RETURN_FALSE; } } else { - intl_error_set(NULL, status, "datefmt_format_object: the passed object " - "must be an instance of either IntlCalendar or DateTimeInterface", - 0); + intl_error_set(NULL, status, "the passed object must be an instance " + "of either IntlCalendar or DateTimeInterface"); RETURN_FALSE; } if (pattern) { StringPiece sp(Z_STRVAL_P(format)); - df = new SimpleDateFormat( + df = std::unique_ptr(new SimpleDateFormat( UnicodeString::fromUTF8(sp), Locale::createFromName(locale_str), - status); + status)); if (U_FAILURE(status)) { - intl_error_set(NULL, status, - "datefmt_format_object: could not create SimpleDateFormat", - 0); - RETVAL_FALSE; - goto cleanup; + intl_error_set(NULL, status, "could not create SimpleDateFormat"); + RETURN_FALSE; } } else { - df = DateFormat::createDateTimeInstance(dateStyle, timeStyle, - Locale::createFromName(locale_str)); + df = std::unique_ptr(DateFormat::createDateTimeInstance(dateStyle, timeStyle, + Locale::createFromName(locale_str))); if (df == NULL) { /* according to ICU sources, this should never happen */ - intl_error_set(NULL, status, - "datefmt_format_object: could not create DateFormat", - 0); - RETVAL_FALSE; - goto cleanup; + intl_error_set(NULL, status, "could not create DateFormat"); + RETURN_FALSE; } } //must be in this order (or have the cal adopt the tz) - df->adoptCalendar(cal); - cal = NULL; - df->adoptTimeZone(timeZone); - timeZone = NULL; + df->adoptCalendar(cal.release()); + df->adoptTimeZone(timeZone.release()); { zend_string *u8str; @@ -228,18 +214,9 @@ U_CFUNC PHP_FUNCTION(datefmt_format_object) u8str = intl_charFromString(result, &status); if (!u8str) { - intl_error_set(NULL, status, - "datefmt_format_object: error converting result to UTF-8", - 0); - RETVAL_FALSE; - goto cleanup; + intl_error_set(NULL, status, "error converting result to UTF-8"); + RETURN_FALSE; } RETVAL_STR(u8str); } - - -cleanup: - delete df; - delete timeZone; - delete cal; } diff --git a/ext/intl/dateformat/dateformat_helpers.cpp b/ext/intl/dateformat/dateformat_helpers.cpp index 2842c520a30..18dc594dedd 100644 --- a/ext/intl/dateformat/dateformat_helpers.cpp +++ b/ext/intl/dateformat/dateformat_helpers.cpp @@ -28,11 +28,10 @@ extern "C" { using icu::GregorianCalendar; -int datefmt_process_calendar_arg( +zend_result datefmt_process_calendar_arg( zend_object *calendar_obj, zend_long calendar_long, bool calendar_is_null, Locale const& locale, - const char *func_name, intl_error *err, Calendar*& cal, zend_long& cal_int_type, bool& calendar_owned + intl_error *err, Calendar*& cal, zend_long& cal_int_type, bool& calendar_owned ) { - char *msg; UErrorCode status = UErrorCode(); if (calendar_is_null) { @@ -45,13 +44,11 @@ int datefmt_process_calendar_arg( } else if (!calendar_obj) { zend_long v = calendar_long; if (v != (zend_long)UCAL_TRADITIONAL && v != (zend_long)UCAL_GREGORIAN) { - spprintf(&msg, 0, "%s: Invalid value for calendar type; it must be " - "one of IntlDateFormatter::TRADITIONAL (locale's default " - "calendar) or IntlDateFormatter::GREGORIAN. " - "Alternatively, it can be an IntlCalendar object", - func_name); - intl_errors_set(err, U_ILLEGAL_ARGUMENT_ERROR, msg, 1); - efree(msg); + intl_errors_set(err, U_ILLEGAL_ARGUMENT_ERROR, + "Invalid value for calendar type; it must be one of " + "IntlDateFormatter::TRADITIONAL (locale's default calendar) or" + " IntlDateFormatter::GREGORIAN. Alternatively, it can be an " + "IntlCalendar object"); return FAILURE; } else if (v == (zend_long)UCAL_TRADITIONAL) { cal = Calendar::createInstance(locale, status); @@ -65,10 +62,7 @@ int datefmt_process_calendar_arg( } else if (calendar_obj) { cal = calendar_fetch_native_calendar(calendar_obj); if (cal == NULL) { - spprintf(&msg, 0, "%s: Found unconstructed IntlCalendar object", - func_name); - intl_errors_set(err, U_ILLEGAL_ARGUMENT_ERROR, msg, 1); - efree(msg); + intl_errors_set(err, U_ILLEGAL_ARGUMENT_ERROR, "Found unconstructed IntlCalendar object"); return FAILURE; } calendar_owned = false; @@ -76,10 +70,8 @@ int datefmt_process_calendar_arg( cal_int_type = -1; } else { - spprintf(&msg, 0, "%s: Invalid calendar argument; should be an integer " - "or an IntlCalendar instance", func_name); - intl_errors_set(err, U_ILLEGAL_ARGUMENT_ERROR, msg, 1); - efree(msg); + intl_errors_set(err, U_ILLEGAL_ARGUMENT_ERROR, + "Invalid calendar argument; should be an integer or an IntlCalendar instance"); return FAILURE; } @@ -87,9 +79,7 @@ int datefmt_process_calendar_arg( status = U_MEMORY_ALLOCATION_ERROR; } if (U_FAILURE(status)) { - spprintf(&msg, 0, "%s: Failure instantiating calendar", func_name); - intl_errors_set(err, U_ILLEGAL_ARGUMENT_ERROR, msg, 1); - efree(msg); + intl_errors_set(err, U_ILLEGAL_ARGUMENT_ERROR, "Failure instantiating calendar"); return FAILURE; } diff --git a/ext/intl/dateformat/dateformat_helpers.h b/ext/intl/dateformat/dateformat_helpers.h index 4140eb730a2..b931d9667e5 100644 --- a/ext/intl/dateformat/dateformat_helpers.h +++ b/ext/intl/dateformat/dateformat_helpers.h @@ -30,9 +30,9 @@ using icu::Locale; using icu::Calendar; using icu::DateFormat; -int datefmt_process_calendar_arg( +zend_result datefmt_process_calendar_arg( zend_object *calendar_obj, zend_long calendar_long, bool calendar_is_null, Locale const& locale, - const char *func_name, intl_error *err, Calendar*& cal, zend_long& cal_int_type, bool& calendar_owned + intl_error *err, Calendar*& cal, zend_long& cal_int_type, bool& calendar_owned ); #endif /* DATEFORMAT_HELPERS_H */ diff --git a/ext/intl/dateformat/dateformat_parse.c b/ext/intl/dateformat/dateformat_parse.c index 2bdde08bcac..b6e9f7c92eb 100644 --- a/ext/intl/dateformat/dateformat_parse.c +++ b/ext/intl/dateformat/dateformat_parse.c @@ -150,7 +150,7 @@ PHP_FUNCTION(datefmt_parse) zend_long long_parse_pos = zval_get_long(z_parse_pos_tmp); if (ZEND_LONG_INT_OVFL(long_parse_pos)) { intl_error_set_code(NULL, U_ILLEGAL_ARGUMENT_ERROR); - intl_error_set_custom_msg(NULL, "String index is out of valid range.", 0); + intl_error_set_custom_msg(NULL, "String index is out of valid range."); RETURN_FALSE; } parse_pos = (int32_t)long_parse_pos; @@ -193,7 +193,7 @@ PHP_METHOD(IntlDateFormatter, parseToCalendar) } if (ZEND_LONG_INT_OVFL(long_parse_pos)) { intl_error_set_code(NULL, U_ILLEGAL_ARGUMENT_ERROR); - intl_error_set_custom_msg(NULL, "String index is out of valid range.", 0); + intl_error_set_custom_msg(NULL, "String index is out of valid range."); RETURN_FALSE; } parse_pos = (int32_t)long_parse_pos; @@ -232,7 +232,7 @@ PHP_FUNCTION(datefmt_localtime) zend_long long_parse_pos = zval_get_long(z_parse_pos_tmp); if (ZEND_LONG_INT_OVFL(long_parse_pos)) { intl_error_set_code(NULL, U_ILLEGAL_ARGUMENT_ERROR); - intl_error_set_custom_msg(NULL, "String index is out of valid range.", 0); + intl_error_set_custom_msg(NULL, "String index is out of valid range."); RETURN_FALSE; } parse_pos = (int32_t)long_parse_pos; diff --git a/ext/intl/dateformat/datepatterngenerator_methods.cpp b/ext/intl/dateformat/datepatterngenerator_methods.cpp index 1b659c7aa20..beaf10d9f50 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, zend_error_handling *error_handling, bool *error_handling_replaced) +static zend_result dtpg_ctor(INTERNAL_FUNCTION_PARAMETERS) { char *locale_str; size_t locale_len = 0; @@ -44,15 +44,10 @@ static zend_result dtpg_ctor(INTERNAL_FUNCTION_PARAMETERS, zend_error_handling * 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) { - intl_errors_set(DTPATTERNGEN_ERROR_P(dtpgo), U_ILLEGAL_ARGUMENT_ERROR, "Cannot call constructor twice", 0); + intl_errors_set(DTPATTERNGEN_ERROR_P(dtpgo), U_ILLEGAL_ARGUMENT_ERROR, "Cannot call constructor twice"); return FAILURE; } @@ -68,8 +63,7 @@ static zend_result dtpg_ctor(INTERNAL_FUNCTION_PARAMETERS, zend_error_handling * if (U_FAILURE(DTPATTERNGEN_ERROR_CODE(dtpgo))) { intl_error_set(NULL, DTPATTERNGEN_ERROR_CODE(dtpgo), - "Error creating DateTimePatternGenerator", - 0); + "Error creating DateTimePatternGenerator"); return FAILURE; } @@ -79,7 +73,7 @@ static zend_result dtpg_ctor(INTERNAL_FUNCTION_PARAMETERS, zend_error_handling * U_CFUNC PHP_METHOD( IntlDatePatternGenerator, create ) { object_init_ex( return_value, IntlDatePatternGenerator_ce_ptr ); - if (dtpg_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, NULL, NULL) == FAILURE) { + if (dtpg_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU) == FAILURE) { zval_ptr_dtor(return_value); RETURN_NULL(); } @@ -87,22 +81,19 @@ U_CFUNC PHP_METHOD( IntlDatePatternGenerator, create ) U_CFUNC PHP_METHOD( IntlDatePatternGenerator, __construct ) { - zend_error_handling error_handling; - bool error_handling_replaced = 0; + const bool old_use_exception = INTL_G(use_exceptions); + const zend_long old_error_level = INTL_G(error_level); + INTL_G(use_exceptions) = true; + INTL_G(error_level) = 0; /* return_value param is being changed, therefore we will always return * NULL here */ return_value = ZEND_THIS; - 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); - } - } - if (error_handling_replaced) { - zend_restore_error_handling(&error_handling); + if (dtpg_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU) == FAILURE) { + ZEND_ASSERT(EG(exception)); } + INTL_G(use_exceptions) = old_use_exception; + INTL_G(error_level) = old_error_level; } diff --git a/ext/intl/formatter/formatter_attr.c b/ext/intl/formatter/formatter_attr.c index 874984f5405..a7cafcf5f97 100644 --- a/ext/intl/formatter/formatter_attr.c +++ b/ext/intl/formatter/formatter_attr.c @@ -226,7 +226,7 @@ PHP_FUNCTION( numfmt_get_symbol ) } if(symbol >= UNUM_FORMAT_SYMBOL_COUNT || symbol < 0) { - intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "numfmt_get_symbol: invalid symbol value", 0 ); + intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "invalid symbol value"); RETURN_FALSE; } @@ -268,7 +268,7 @@ PHP_FUNCTION( numfmt_set_symbol ) } if (symbol >= UNUM_FORMAT_SYMBOL_COUNT || symbol < 0) { - intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "numfmt_set_symbol: invalid symbol value", 0 ); + intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "invalid symbol value"); RETURN_FALSE; } @@ -355,7 +355,7 @@ PHP_FUNCTION( numfmt_set_pattern ) if (U_FAILURE(INTL_DATA_ERROR_CODE(nfo))) { char *msg; spprintf(&msg, 0, "Error setting pattern value at line %d, offset %d", spattern_error.line, spattern_error.offset); - intl_errors_set_custom_msg(INTL_DATA_ERROR_P(nfo), msg, 1); + intl_errors_set_custom_msg(INTL_DATA_ERROR_P(nfo), msg); efree(msg); RETURN_FALSE; } diff --git a/ext/intl/formatter/formatter_format.c b/ext/intl/formatter/formatter_format.c index 54c5d92fe18..5be732dde77 100644 --- a/ext/intl/formatter/formatter_format.c +++ b/ext/intl/formatter/formatter_format.c @@ -164,7 +164,7 @@ PHP_FUNCTION( numfmt_format_currency ) if( U_FAILURE( INTL_DATA_ERROR_CODE((nfo)) ) ) { intl_error_set_code( NULL, INTL_DATA_ERROR_CODE((nfo)) ); - intl_errors_set_custom_msg( INTL_DATA_ERROR_P(nfo), "Number formatting failed", 0 ); + intl_errors_set_custom_msg( INTL_DATA_ERROR_P(nfo), "Number formatting failed"); RETVAL_FALSE; if (formatted != format_buf) { efree(formatted); diff --git a/ext/intl/formatter/formatter_main.c b/ext/intl/formatter/formatter_main.c index 6f8fb98d214..6f92b7e787b 100644 --- a/ext/intl/formatter/formatter_main.c +++ b/ext/intl/formatter/formatter_main.c @@ -24,7 +24,7 @@ #include "intl_convert.h" /* {{{ */ -static int numfmt_ctor(INTERNAL_FUNCTION_PARAMETERS, zend_error_handling *error_handling, bool *error_handling_replaced) +static int numfmt_ctor(INTERNAL_FUNCTION_PARAMETERS) { char* locale; char* pattern = NULL; @@ -41,11 +41,6 @@ static int numfmt_ctor(INTERNAL_FUNCTION_PARAMETERS, zend_error_handling *error_ Z_PARAM_STRING_OR_NULL(pattern, pattern_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; - } - INTL_CHECK_LOCALE_LEN_OR_FAILURE(locale_len); object = return_value; FORMATTER_METHOD_FETCH_OBJECT_NO_CHECK; @@ -57,7 +52,7 @@ static int numfmt_ctor(INTERNAL_FUNCTION_PARAMETERS, zend_error_handling *error_ /* Convert pattern (if specified) to UTF-16. */ if(pattern && pattern_len) { intl_convert_utf8_to_utf16(&spattern, &spattern_len, pattern, pattern_len, &INTL_DATA_ERROR_CODE(nfo)); - INTL_CTOR_CHECK_STATUS(nfo, "numfmt_create: error converting pattern to UTF-16"); + INTL_CTOR_CHECK_STATUS(nfo, "error converting pattern to UTF-16"); } if(locale_len == 0) { @@ -76,7 +71,7 @@ static int numfmt_ctor(INTERNAL_FUNCTION_PARAMETERS, zend_error_handling *error_ efree(spattern); } - INTL_CTOR_CHECK_STATUS(nfo, "numfmt_create: number formatter creation failed"); + INTL_CTOR_CHECK_STATUS(nfo, "number formatter creation failed"); return SUCCESS; } /* }}} */ @@ -85,7 +80,7 @@ static int numfmt_ctor(INTERNAL_FUNCTION_PARAMETERS, zend_error_handling *error_ PHP_FUNCTION( numfmt_create ) { object_init_ex( return_value, NumberFormatter_ce_ptr ); - if (numfmt_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, NULL, NULL) == FAILURE) { + if (numfmt_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU) == FAILURE) { zval_ptr_dtor(return_value); RETURN_NULL(); } @@ -95,18 +90,17 @@ PHP_FUNCTION( numfmt_create ) /* {{{ NumberFormatter object constructor. */ PHP_METHOD( NumberFormatter, __construct ) { - zend_error_handling error_handling; - bool error_handling_replaced = 0; + const bool old_use_exception = INTL_G(use_exceptions); + const zend_long old_error_level = INTL_G(error_level); + INTL_G(use_exceptions) = true; + INTL_G(error_level) = 0; return_value = ZEND_THIS; - 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); - } - } - if (error_handling_replaced) { - zend_restore_error_handling(&error_handling); + if (numfmt_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU) == FAILURE) { + ZEND_ASSERT(EG(exception)); } + INTL_G(use_exceptions) = old_use_exception; + INTL_G(error_level) = old_error_level; } /* }}} */ diff --git a/ext/intl/grapheme/grapheme_string.c b/ext/intl/grapheme/grapheme_string.c index 34dd2ed369c..8abef7dd560 100644 --- a/ext/intl/grapheme/grapheme_string.c +++ b/ext/intl/grapheme/grapheme_string.c @@ -57,7 +57,7 @@ PHP_FUNCTION(grapheme_strlen) intl_error_set_code( NULL, status ); /* Set error messages. */ - intl_error_set_custom_msg( NULL, "Error converting input string to UTF-16", 0 ); + intl_error_set_custom_msg( NULL, "Error converting input string to UTF-16"); if (ustring) { efree( ustring ); } @@ -370,7 +370,7 @@ PHP_FUNCTION(grapheme_substr) grapheme_substr_ascii(str, str_len, start, (int32_t)length, &sub_str, &asub_str_len); if ( NULL == sub_str ) { - intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "grapheme_substr: invalid parameters", 1 ); + intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "invalid parameters"); RETURN_FALSE; } @@ -387,7 +387,7 @@ PHP_FUNCTION(grapheme_substr) intl_error_set_code( NULL, status ); /* Set error messages. */ - intl_error_set_custom_msg( NULL, "Error converting input string to UTF-16", 0 ); + intl_error_set_custom_msg( NULL, "Error converting input string to UTF-16"); if (ustr) { efree( ustr ); } @@ -455,7 +455,7 @@ PHP_FUNCTION(grapheme_substr) intl_error_set_code( NULL, status ); /* Set error messages. */ - intl_error_set_custom_msg( NULL, "Error converting output string to UTF-8", 0 ); + intl_error_set_custom_msg( NULL, "Error converting output string to UTF-8"); RETURN_FALSE; } @@ -524,7 +524,7 @@ PHP_FUNCTION(grapheme_substr) intl_error_set_code( NULL, status ); /* Set error messages. */ - intl_error_set_custom_msg( NULL, "Error converting output string to UTF-8", 0 ); + intl_error_set_custom_msg( NULL, "Error converting output string to UTF-8"); RETURN_FALSE; } @@ -747,7 +747,7 @@ PHP_FUNCTION(grapheme_extract) } if ( lstart > INT32_MAX || lstart < 0 || (size_t)lstart >= str_len ) { - intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "grapheme_extract: start not contained in string", 0 ); + intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "start not contained in string"); RETURN_FALSE; } @@ -779,7 +779,7 @@ PHP_FUNCTION(grapheme_extract) start++; if ( pstr >= str_end ) { intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, - "grapheme_extract: invalid input string", 0 ); + "grapheme_extract: invalid input string"); RETURN_FALSE; } @@ -808,7 +808,7 @@ PHP_FUNCTION(grapheme_extract) intl_error_set_code( NULL, status ); /* Set error messages. */ - intl_error_set_custom_msg( NULL, "Error opening UTF-8 text", 0 ); + intl_error_set_custom_msg( NULL, "Error opening UTF-8 text"); RETURN_FALSE; } @@ -870,7 +870,7 @@ PHP_FUNCTION(grapheme_str_split) intl_error_set_code( NULL, ustatus ); /* Set error messages. */ - intl_error_set_custom_msg( NULL, "Error opening UTF-8 text", 0 ); + intl_error_set_custom_msg( NULL, "Error opening UTF-8 text"); RETURN_FALSE; } @@ -974,7 +974,7 @@ PHP_FUNCTION(grapheme_levenshtein) if (U_FAILURE(ustatus)) { intl_error_set_code(NULL, ustatus); - intl_error_set_custom_msg(NULL, "Error converting input string to UTF-16", 0); + intl_error_set_custom_msg(NULL, "Error converting input string to UTF-16"); RETVAL_FALSE; goto out_ustring1; } @@ -984,7 +984,7 @@ PHP_FUNCTION(grapheme_levenshtein) if (U_FAILURE(ustatus)) { intl_error_set_code(NULL, ustatus); - intl_error_set_custom_msg(NULL, "Error converting input string to UTF-16", 0); + intl_error_set_custom_msg(NULL, "Error converting input string to UTF-16"); RETVAL_FALSE; goto out_ustring2; } @@ -1013,7 +1013,7 @@ PHP_FUNCTION(grapheme_levenshtein) bi1 = grapheme_get_break_iterator(u_break_iterator_buffer1, &ustatus); if (U_FAILURE(ustatus)) { intl_error_set_code(NULL, ustatus); - intl_error_set_custom_msg(NULL, "Error on grapheme_get_break_iterator for argument #1 ($string1)", 0); + intl_error_set_custom_msg(NULL, "Error on grapheme_get_break_iterator for argument #1 ($string1)"); RETVAL_FALSE; goto out_bi1; } @@ -1021,7 +1021,7 @@ PHP_FUNCTION(grapheme_levenshtein) bi2 = grapheme_get_break_iterator(u_break_iterator_buffer2, &ustatus); if (U_FAILURE(ustatus)) { intl_error_set_code(NULL, ustatus); - intl_error_set_custom_msg(NULL, "Error on grapheme_get_break_iterator for argument #2 ($string2)", 0); + intl_error_set_custom_msg(NULL, "Error on grapheme_get_break_iterator for argument #2 ($string2)"); RETVAL_FALSE; goto out_bi2; } @@ -1030,7 +1030,7 @@ PHP_FUNCTION(grapheme_levenshtein) if (U_FAILURE(ustatus)) { intl_error_set_code(NULL, ustatus); - intl_error_set_custom_msg(NULL, "Error on ubrk_setText for argument #1 ($string1)", 0); + intl_error_set_custom_msg(NULL, "Error on ubrk_setText for argument #1 ($string1)"); RETVAL_FALSE; goto out_bi2; } @@ -1039,7 +1039,7 @@ PHP_FUNCTION(grapheme_levenshtein) if (U_FAILURE(ustatus)) { intl_error_set_code(NULL, ustatus); - intl_error_set_custom_msg(NULL, "Error on ubrk_setText for argument #2 ($string2)", 0); + intl_error_set_custom_msg(NULL, "Error on ubrk_setText for argument #2 ($string2)"); RETVAL_FALSE; goto out_bi2; } @@ -1047,7 +1047,7 @@ PHP_FUNCTION(grapheme_levenshtein) if (U_FAILURE(ustatus)) { intl_error_set_code(NULL, ustatus); - intl_error_set_custom_msg(NULL, "Error on ucol_open", 0); + intl_error_set_custom_msg(NULL, "Error on ucol_open"); RETVAL_FALSE; goto out_collator; } diff --git a/ext/intl/grapheme/grapheme_util.c b/ext/intl/grapheme/grapheme_util.c index 501b9dfb221..d4b6c1cbfd8 100644 --- a/ext/intl/grapheme/grapheme_util.c +++ b/ext/intl/grapheme/grapheme_util.c @@ -87,7 +87,7 @@ void grapheme_substr_ascii(char *str, size_t str_len, int32_t f, int32_t l, char #define STRPOS_CHECK_STATUS(status, error) \ if ( U_FAILURE( (status) ) ) { \ intl_error_set_code( NULL, (status) ); \ - intl_error_set_custom_msg( NULL, (error), 0 ); \ + intl_error_set_custom_msg( NULL, (error)); \ ret_pos = -1; \ goto finish; \ } diff --git a/ext/intl/idn/idn.c b/ext/intl/idn/idn.cpp similarity index 95% rename from ext/intl/idn/idn.c rename to ext/intl/idn/idn.cpp index cd4546ad7f8..6c7e4d8c6d6 100644 --- a/ext/intl/idn/idn.c +++ b/ext/intl/idn/idn.cpp @@ -20,13 +20,17 @@ #include #endif -#include - +extern "C" { +#include "../php_intl.h" +} #include #include #include "idn.h" + +extern "C" { #include "intl_error.h" +} /* }}} */ enum { @@ -39,12 +43,7 @@ static zend_result php_intl_idn_check_status(UErrorCode err, const char *msg) { intl_error_set_code(NULL, err); if (U_FAILURE(err)) { - char *buff; - spprintf(&buff, 0, "%s: %s", - get_active_function_name(), - msg); - intl_error_set_custom_msg(NULL, buff, 1); - efree(buff); + intl_error_set_custom_msg(NULL, msg); return FAILURE; } @@ -145,7 +144,7 @@ static void php_intl_idn_handoff(INTERNAL_FUNCTION_PARAMETERS, int mode) } /* {{{ Converts an Unicode domain to ASCII representation, as defined in the IDNA RFC */ -PHP_FUNCTION(idn_to_ascii) +U_CFUNC PHP_FUNCTION(idn_to_ascii) { php_intl_idn_handoff(INTERNAL_FUNCTION_PARAM_PASSTHRU, INTL_IDN_TO_ASCII); } @@ -153,7 +152,7 @@ PHP_FUNCTION(idn_to_ascii) /* {{{ Converts an ASCII representation of the domain to Unicode (UTF-8), as defined in the IDNA RFC */ -PHP_FUNCTION(idn_to_utf8) +U_CFUNC PHP_FUNCTION(idn_to_utf8) { php_intl_idn_handoff(INTERNAL_FUNCTION_PARAM_PASSTHRU, INTL_IDN_TO_UTF8); } diff --git a/ext/intl/intl_data.h b/ext/intl/intl_data.h index 23320a9ff11..c818427e07e 100644 --- a/ext/intl/intl_data.h +++ b/ext/intl/intl_data.h @@ -48,7 +48,7 @@ typedef struct _intl_data { intl_error_set_code( NULL, (err) ); \ if( U_FAILURE((err)) ) \ { \ - intl_error_set_custom_msg( NULL, msg, 0 ); \ + intl_error_set_custom_msg( NULL, msg); \ RETURN_FALSE; \ } @@ -57,7 +57,7 @@ typedef struct _intl_data { intl_error_set_code( NULL, (err) ); \ if( U_FAILURE((err)) ) \ { \ - intl_error_set_custom_msg( NULL, msg, 0 ); \ + intl_error_set_custom_msg( NULL, msg); \ RETURN_NULL(); \ } @@ -67,7 +67,7 @@ typedef struct _intl_data { intl_error_set_code( NULL, INTL_DATA_ERROR_CODE((obj)) ); \ if( U_FAILURE( INTL_DATA_ERROR_CODE((obj)) ) ) \ { \ - intl_errors_set_custom_msg( INTL_DATA_ERROR_P((obj)), msg, 0 ); \ + intl_errors_set_custom_msg( INTL_DATA_ERROR_P((obj)), msg); \ RETURN_FALSE; \ } @@ -76,7 +76,7 @@ typedef struct _intl_data { intl_error_set_code( NULL, INTL_DATA_ERROR_CODE((obj)) ); \ if( U_FAILURE( INTL_DATA_ERROR_CODE((obj)) ) ) \ { \ - intl_errors_set_custom_msg( INTL_DATA_ERROR_P((obj)), msg, 0 ); \ + intl_errors_set_custom_msg( INTL_DATA_ERROR_P((obj)), msg); \ RETVAL_FALSE; \ goto label; \ } @@ -86,7 +86,7 @@ typedef struct _intl_data { intl_error_set_code( NULL, INTL_DATA_ERROR_CODE((obj)) ); \ if( U_FAILURE( INTL_DATA_ERROR_CODE((obj)) ) ) \ { \ - intl_errors_set_custom_msg( INTL_DATA_ERROR_P((obj)), msg, 0 ); \ + intl_errors_set_custom_msg( INTL_DATA_ERROR_P((obj)), msg); \ zval_ptr_dtor(return_value); \ RETURN_NULL(); \ } @@ -96,7 +96,7 @@ typedef struct _intl_data { intl_error_set_code( NULL, INTL_DATA_ERROR_CODE((obj)) ); \ if( U_FAILURE( INTL_DATA_ERROR_CODE((obj)) ) ) \ { \ - intl_errors_set_custom_msg( INTL_DATA_ERROR_P((obj)), msg, 0 ); \ + intl_errors_set_custom_msg( INTL_DATA_ERROR_P((obj)), msg); \ return FAILURE; \ } @@ -117,7 +117,7 @@ typedef struct _intl_data { if((locale_len) > INTL_MAX_LOCALE_LEN) { \ char *_msg; \ spprintf(&_msg, 0, "Locale string too long, should be no longer than %d characters", INTL_MAX_LOCALE_LEN); \ - intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, _msg, 1); \ + intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, _msg); \ efree(_msg); \ RETURN_NULL(); \ } @@ -126,7 +126,7 @@ typedef struct _intl_data { if((locale_len) > INTL_MAX_LOCALE_LEN) { \ char *_msg; \ spprintf(&_msg, 0, "Locale string too long, should be no longer than %d characters", INTL_MAX_LOCALE_LEN); \ - intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, _msg, 1); \ + intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, _msg); \ efree(_msg); \ return FAILURE; \ } diff --git a/ext/intl/intl_error.c b/ext/intl/intl_error.c index a1c3a9efb2d..be6e53fb543 100644 --- a/ext/intl/intl_error.c +++ b/ext/intl/intl_error.c @@ -42,12 +42,10 @@ static void intl_free_custom_error_msg( intl_error* err ) if( !err && !( err = intl_g_error_get( ) ) ) return; - if(err->free_custom_error_message ) { - efree( err->custom_error_message ); + if (err->custom_error_message) { + zend_string_release_ex(err->custom_error_message, false); + err->custom_error_message = NULL; } - - err->custom_error_message = NULL; - err->free_custom_error_message = 0; } /* }}} */ @@ -70,7 +68,6 @@ void intl_error_init( intl_error* err ) err->code = U_ZERO_ERROR; err->custom_error_message = NULL; - err->free_custom_error_message = 0; } /* }}} */ @@ -87,28 +84,41 @@ void intl_error_reset( intl_error* err ) /* }}} */ /* {{{ Set last error message to msg copying it if needed. */ -void intl_error_set_custom_msg( intl_error* err, const char* msg, int copyMsg ) +void intl_error_set_custom_msg( intl_error* err, const char* msg) { - if( !msg ) + /* See ext/intl/tests/bug70451.phpt and uchar.c:zif_IntlChar_charFromName */ + if (UNEXPECTED(msg == NULL)) { return; + } + + zend_string *method_or_func = get_active_function_or_method_name(); + zend_string *prefixed_message = zend_string_concat3( + ZSTR_VAL(method_or_func), ZSTR_LEN(method_or_func), + ZEND_STRL("(): "), + msg, strlen(msg) + ); + zend_string_release_ex(method_or_func, false); if( !err ) { - if( INTL_G( error_level ) ) + if (INTL_G(error_level)) { + /* Docref will prefix the function/method for us, so use original message */ php_error_docref( NULL, INTL_G( error_level ), "%s", msg ); - if( INTL_G( use_exceptions ) ) - zend_throw_exception_ex( IntlException_ce_ptr, 0, "%s", msg ); + } + if (INTL_G(use_exceptions)) { + /* Use this variant as we have a zend_string already */ + zend_throw_error_exception(IntlException_ce_ptr, prefixed_message, 0, 0); + } } - if( !err && !( err = intl_g_error_get( ) ) ) + if (!err && !(err = intl_g_error_get() )) { + zend_string_release_ex(prefixed_message, false); return; + } /* Free previous message if any */ intl_free_custom_error_msg( err ); - /* Mark message copied if any */ - err->free_custom_error_message = copyMsg; - /* Set user's error text message */ - err->custom_error_message = copyMsg ? estrdup( msg ) : (char *) msg; + err->custom_error_message = prefixed_message; } /* }}} */ @@ -116,21 +126,22 @@ void intl_error_set_custom_msg( intl_error* err, const char* msg, int copyMsg ) zend_string * intl_error_get_message( intl_error* err ) { const char *uErrorName = NULL; - zend_string *errMessage = 0; + zend_string *errMessage = NULL; if( !err && !( err = intl_g_error_get( ) ) ) return ZSTR_EMPTY_ALLOC(); uErrorName = u_errorName( err->code ); + size_t uErrorLen = strlen(uErrorName); /* Format output string */ - if( err->custom_error_message ) - { - errMessage = strpprintf(0, "%s: %s", err->custom_error_message, uErrorName ); - } - else - { - errMessage = strpprintf(0, "%s", uErrorName ); + if (err->custom_error_message) { + errMessage = zend_string_concat3( + ZSTR_VAL(err->custom_error_message), ZSTR_LEN(err->custom_error_message), + ZEND_STRL(": "), + uErrorName, uErrorLen); + } else { + errMessage = zend_string_init(uErrorName, strlen(uErrorName), false); } return errMessage; @@ -158,18 +169,18 @@ UErrorCode intl_error_get_code( intl_error* err ) /* }}} */ /* {{{ Set error code and message. */ -void intl_error_set( intl_error* err, UErrorCode code, const char* msg, int copyMsg ) +void intl_error_set( intl_error* err, UErrorCode code, const char* msg) { intl_error_set_code( err, code ); - intl_error_set_custom_msg( err, msg, copyMsg ); + intl_error_set_custom_msg( err, msg); } /* }}} */ /* {{{ Set error code and message. */ -void intl_errors_set( intl_error* err, UErrorCode code, const char* msg, int copyMsg ) +void intl_errors_set( intl_error* err, UErrorCode code, const char* msg) { intl_errors_set_code( err, code ); - intl_errors_set_custom_msg( err, msg, copyMsg ); + intl_errors_set_custom_msg( err, msg); } /* }}} */ @@ -184,12 +195,12 @@ void intl_errors_reset( intl_error* err ) /* }}} */ /* {{{ */ -void intl_errors_set_custom_msg( intl_error* err, const char* msg, int copyMsg ) +void intl_errors_set_custom_msg(intl_error* err, const char* msg) { if(err) { - intl_error_set_custom_msg( err, msg, copyMsg ); + intl_error_set_custom_msg( err, msg); } - intl_error_set_custom_msg( NULL, msg, copyMsg ); + intl_error_set_custom_msg( NULL, msg); } /* }}} */ diff --git a/ext/intl/intl_error.h b/ext/intl/intl_error.h index 74bf0d8a43e..8a9bff0b271 100644 --- a/ext/intl/intl_error.h +++ b/ext/intl/intl_error.h @@ -23,26 +23,25 @@ #define INTL_ERROR_CODE(e) (e).code -typedef struct _intl_error { - UErrorCode code; - int free_custom_error_message; - char* custom_error_message; +typedef struct { + zend_string *custom_error_message; + UErrorCode code; } intl_error; intl_error* intl_error_create( void ); void intl_error_init( intl_error* err ); void intl_error_reset( intl_error* err ); void intl_error_set_code( intl_error* err, UErrorCode err_code ); -void intl_error_set_custom_msg( intl_error* err, const char* msg, int copyMsg ); -void intl_error_set( intl_error* err, UErrorCode code, const char* msg, int copyMsg ); +void intl_error_set_custom_msg( intl_error* err, const char* msg); +void intl_error_set( intl_error* err, UErrorCode code, const char* msg); UErrorCode intl_error_get_code( intl_error* err ); zend_string* intl_error_get_message( intl_error* err ); // Wrappers to synchonize object's and global error structures. void intl_errors_reset( intl_error* err ); -void intl_errors_set_custom_msg( intl_error* err, const char* msg, int copyMsg ); +void intl_errors_set_custom_msg( intl_error* err, const char* msg); void intl_errors_set_code( intl_error* err, UErrorCode err_code ); -void intl_errors_set( intl_error* err, UErrorCode code, const char* msg, int copyMsg ); +void intl_errors_set( intl_error* err, UErrorCode code, const char* msg); // Other error helpers smart_str intl_parse_error_to_string( UParseError* pe ); diff --git a/ext/intl/listformatter/listformatter_class.c b/ext/intl/listformatter/listformatter_class.c index f1a5039079b..1aa849370ab 100644 --- a/ext/intl/listformatter/listformatter_class.c +++ b/ext/intl/listformatter/listformatter_class.c @@ -72,7 +72,7 @@ PHP_METHOD(IntlListFormatter, __construct) } if (locale_len > INTL_MAX_LOCALE_LEN) { - zend_argument_value_error(1, "Locale string too long, should be no longer than %d characters", INTL_MAX_LOCALE_LEN); + zend_argument_value_error(1, "must be less than or equal to %d characters", INTL_MAX_LOCALE_LEN); RETURN_THROWS(); } @@ -109,7 +109,7 @@ PHP_METHOD(IntlListFormatter, __construct) #endif if (U_FAILURE(status)) { - intl_error_set(NULL, status, "Constructor failed", 0); + intl_error_set(NULL, status, "Constructor failed"); zend_throw_exception(IntlException_ce_ptr, "Constructor failed", 0); RETURN_THROWS(); } @@ -154,7 +154,7 @@ PHP_METHOD(IntlListFormatter, format) } efree(items); efree(itemLengths); - intl_error_set(NULL, status, "Failed to convert string to UTF-16", 0); + intl_error_set(NULL, status, "Failed to convert string to UTF-16"); RETURN_FALSE; } @@ -170,7 +170,7 @@ PHP_METHOD(IntlListFormatter, format) resultLength = ulistfmt_format(LISTFORMATTER_OBJECT(obj), items, itemLengths, count, NULL, 0, &status); if (U_FAILURE(status) && status != U_BUFFER_OVERFLOW_ERROR) { - intl_error_set(NULL, status, "Failed to format list", 0); + intl_error_set(NULL, status, "Failed to format list"); RETVAL_FALSE; goto cleanup; } @@ -184,7 +184,7 @@ PHP_METHOD(IntlListFormatter, format) if (result) { efree(result); } - intl_error_set(NULL, status, "Failed to format list", 0); + intl_error_set(NULL, status, "Failed to format list"); RETVAL_FALSE; goto cleanup; } @@ -194,7 +194,7 @@ PHP_METHOD(IntlListFormatter, format) efree(result); if (!ret) { - intl_error_set(NULL, status, "Failed to convert result to UTF-8", 0); + intl_error_set(NULL, status, "Failed to convert result to UTF-8"); RETVAL_FALSE; } else { RETVAL_NEW_STR(ret); diff --git a/ext/intl/locale/locale.c b/ext/intl/locale/locale.cpp similarity index 100% rename from ext/intl/locale/locale.c rename to ext/intl/locale/locale.cpp diff --git a/ext/intl/locale/locale_class.c b/ext/intl/locale/locale_class.cpp similarity index 95% rename from ext/intl/locale/locale_class.c rename to ext/intl/locale/locale_class.cpp index cbde2a5fb07..75fde45d53d 100644 --- a/ext/intl/locale/locale_class.c +++ b/ext/intl/locale/locale_class.cpp @@ -13,11 +13,13 @@ */ #include +extern "C" { #include "php_intl.h" #include "intl_error.h" #include "locale_class.h" #include "locale.h" #include "locale_arginfo.h" +} zend_class_entry *Locale_ce_ptr = NULL; @@ -28,7 +30,7 @@ zend_class_entry *Locale_ce_ptr = NULL; /* {{{ locale_register_Locale_class * Initialize 'Locale' class */ -void locale_register_Locale_class( void ) +U_CFUNC void locale_register_Locale_class( void ) { /* Create and register 'Locale' class. */ Locale_ce_ptr = register_class_Locale(); diff --git a/ext/intl/locale/locale_class.h b/ext/intl/locale/locale_class.h index aa339d75db9..64a661ca2b4 100644 --- a/ext/intl/locale/locale_class.h +++ b/ext/intl/locale/locale_class.h @@ -31,7 +31,7 @@ typedef struct { } Locale_object; -void locale_register_Locale_class( void ); +U_CFUNC void locale_register_Locale_class( void ); extern zend_class_entry *Locale_ce_ptr; diff --git a/ext/intl/locale/locale_methods.c b/ext/intl/locale/locale_methods.cpp similarity index 92% rename from ext/intl/locale/locale_methods.c rename to ext/intl/locale/locale_methods.cpp index 8b63007c5d8..fd8712b3b46 100644 --- a/ext/intl/locale/locale_methods.c +++ b/ext/intl/locale/locale_methods.cpp @@ -21,6 +21,7 @@ #include #include +extern "C" { #include "php_intl.h" #include "locale.h" #include "locale_class.h" @@ -32,6 +33,7 @@ #include #include "main/php_ini.h" #include "zend_smart_str.h" +} ZEND_EXTERN_MODULE_GLOBALS( intl ) @@ -296,7 +298,7 @@ static zend_off_t getSingletonPos(const char* str) /* {{{ Get default locale */ /* }}} */ /* {{{ Get default locale */ -PHP_NAMED_FUNCTION(zif_locale_get_default) +U_CFUNC PHP_NAMED_FUNCTION(zif_locale_get_default) { ZEND_PARSE_PARAMETERS_NONE(); @@ -308,7 +310,7 @@ PHP_NAMED_FUNCTION(zif_locale_get_default) /* {{{ Set default locale */ /* }}} */ /* {{{ Set default locale */ -PHP_NAMED_FUNCTION(zif_locale_set_default) +U_CFUNC PHP_NAMED_FUNCTION(zif_locale_set_default) { zend_string* locale_name; zend_string *ini_name; @@ -471,7 +473,6 @@ static void get_icu_value_src_php( char* tag_name, INTERNAL_FUNCTION_PARAMETERS) size_t loc_name_len = 0; zend_string* tag_value = NULL; - char* empty_result = ""; int result = 0; char* msg = NULL; @@ -499,19 +500,18 @@ static void get_icu_value_src_php( char* tag_name, INTERNAL_FUNCTION_PARAMETERS) if( tag_value){ zend_string_release_ex( tag_value, 0 ); } - RETURN_STRING( empty_result); + RETURN_EMPTY_STRING(); } /* value found */ if( tag_value){ - RETVAL_STR( tag_value ); - return; + RETURN_STR( tag_value ); } /* Error encountered while fetching the value */ if( result ==0) { - spprintf(&msg , 0, "locale_get_%s : unable to get locale %s", tag_name , tag_name ); - intl_error_set( NULL, status, msg , 1 ); + spprintf(&msg , 0, "unable to get locale %s", tag_name ); + intl_error_set( NULL, status, msg); efree(msg); RETURN_NULL(); } @@ -520,21 +520,21 @@ static void get_icu_value_src_php( char* tag_name, INTERNAL_FUNCTION_PARAMETERS) /* }}} */ /* {{{ gets the script for the $locale */ -PHP_FUNCTION( locale_get_script ) +U_CFUNC PHP_FUNCTION( locale_get_script ) { get_icu_value_src_php( LOC_SCRIPT_TAG , INTERNAL_FUNCTION_PARAM_PASSTHRU ); } /* }}} */ /* {{{ gets the region for the $locale */ -PHP_FUNCTION( locale_get_region ) +U_CFUNC PHP_FUNCTION( locale_get_region ) { get_icu_value_src_php( LOC_REGION_TAG , INTERNAL_FUNCTION_PARAM_PASSTHRU ); } /* }}} */ /* {{{ gets the primary language for the $locale */ -PHP_FUNCTION(locale_get_primary_language ) +U_CFUNC PHP_FUNCTION(locale_get_primary_language ) { get_icu_value_src_php( LOC_LANG_TAG , INTERNAL_FUNCTION_PARAM_PASSTHRU ); } @@ -575,9 +575,7 @@ static void get_icu_disp_value_src_php( char* tag_name, INTERNAL_FUNCTION_PARAME if(loc_name_len > ULOC_FULLNAME_CAPACITY) { /* See bug 67397: overlong locale names cause trouble in uloc_getDisplayName */ - spprintf(&msg , 0, "locale_get_display_%s : name too long", tag_name ); - intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, msg , 1 ); - efree(msg); + intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "name too long"); RETURN_FALSE; } @@ -610,7 +608,7 @@ static void get_icu_disp_value_src_php( char* tag_name, INTERNAL_FUNCTION_PARAME /* Get the disp_value for the given locale */ do{ - disp_name = erealloc( disp_name , buflen * sizeof(UChar) ); + disp_name = reinterpret_cast(erealloc( disp_name , buflen * sizeof(UChar) )); disp_name_len = buflen; if( strcmp(tag_name , LOC_LANG_TAG)==0 ){ @@ -634,8 +632,8 @@ static void get_icu_disp_value_src_php( char* tag_name, INTERNAL_FUNCTION_PARAME continue; } - spprintf(&msg, 0, "locale_get_display_%s : unable to get locale %s", tag_name , tag_name ); - intl_error_set( NULL, status, msg , 1 ); + spprintf(&msg, 0, "unable to get locale %s", tag_name ); + intl_error_set( NULL, status, msg); efree(msg); if( disp_name){ efree( disp_name ); @@ -663,8 +661,8 @@ static void get_icu_disp_value_src_php( char* tag_name, INTERNAL_FUNCTION_PARAME efree( disp_name ); if( !u8str ) { - spprintf(&msg, 0, "locale_get_display_%s :error converting display name for %s to UTF-8", tag_name , tag_name ); - intl_error_set( NULL, status, msg , 1 ); + spprintf(&msg, 0, "error converting display name for %s to UTF-8", tag_name ); + intl_error_set( NULL, status, msg); efree(msg); RETURN_FALSE; } @@ -674,28 +672,28 @@ static void get_icu_disp_value_src_php( char* tag_name, INTERNAL_FUNCTION_PARAME /* }}} */ /* {{{ gets the name for the $locale in $in_locale or default_locale */ -PHP_FUNCTION(locale_get_display_name) +U_CFUNC PHP_FUNCTION(locale_get_display_name) { get_icu_disp_value_src_php( DISP_NAME , INTERNAL_FUNCTION_PARAM_PASSTHRU ); } /* }}} */ /* {{{ gets the language for the $locale in $in_locale or default_locale */ -PHP_FUNCTION(locale_get_display_language) +U_CFUNC PHP_FUNCTION(locale_get_display_language) { get_icu_disp_value_src_php( LOC_LANG_TAG , INTERNAL_FUNCTION_PARAM_PASSTHRU ); } /* }}} */ /* {{{ gets the script for the $locale in $in_locale or default_locale */ -PHP_FUNCTION(locale_get_display_script) +U_CFUNC PHP_FUNCTION(locale_get_display_script) { get_icu_disp_value_src_php( LOC_SCRIPT_TAG , INTERNAL_FUNCTION_PARAM_PASSTHRU ); } /* }}} */ /* {{{ gets the region for the $locale in $in_locale or default_locale */ -PHP_FUNCTION(locale_get_display_region) +U_CFUNC PHP_FUNCTION(locale_get_display_region) { get_icu_disp_value_src_php( LOC_REGION_TAG , INTERNAL_FUNCTION_PARAM_PASSTHRU ); } @@ -709,7 +707,7 @@ PHP_FUNCTION(locale_get_display_region) * proto static string get_display_variant($locale, $in_locale = null) * gets the variant for the $locale in $in_locale or default_locale */ -PHP_FUNCTION(locale_get_display_variant) +U_CFUNC PHP_FUNCTION(locale_get_display_variant) { get_icu_disp_value_src_php( LOC_VARIANT_TAG , INTERNAL_FUNCTION_PARAM_PASSTHRU ); } @@ -721,7 +719,7 @@ PHP_FUNCTION(locale_get_display_variant) /* {{{ return an associative array containing keyword-value * pairs for this locale. The keys are keys to the array (doh!) */ -PHP_FUNCTION( locale_get_keywords ) +U_CFUNC PHP_FUNCTION( locale_get_keywords ) { UEnumeration* e = NULL; UErrorCode status = U_ZERO_ERROR; @@ -771,7 +769,7 @@ PHP_FUNCTION( locale_get_keywords ) kw_value_str = zend_string_truncate(kw_value_str, kw_value_len, 0); } if (U_FAILURE(status)) { - intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "locale_get_keywords: Error encountered while getting the keyword value for the keyword", 0 ); + intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "Error encountered while getting the keyword value for the keyword"); if( kw_value_str){ zend_string_efree( kw_value_str ); } @@ -791,7 +789,7 @@ PHP_FUNCTION( locale_get_keywords ) /* {{{ @return string the canonicalized locale * }}} */ /* {{{ @param string $locale The locale string to canonicalize */ -PHP_FUNCTION(locale_canonicalize) +U_CFUNC PHP_FUNCTION(locale_canonicalize) { get_icu_value_src_php( LOC_CANONICALIZE_TAG , INTERNAL_FUNCTION_PARAM_PASSTHRU ); } @@ -923,7 +921,7 @@ static int handleAppendResult( int result, smart_str* loc_name) intl_error_reset( NULL ); if( result == FAILURE) { intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, - "locale_compose: parameter array element is not a string", 0 ); + "parameter array element is not a string"); smart_str_free(loc_name); return 0; } @@ -936,9 +934,9 @@ static int handleAppendResult( int result, smart_str* loc_name) * }}} */ /* {{{ Creates a locale by combining the parts of locale-ID passed * }}} */ -PHP_FUNCTION(locale_compose) +U_CFUNC PHP_FUNCTION(locale_compose) { - smart_str loc_name_s = {0}; + smart_str loc_name_s = {NULL, 0}; smart_str *loc_name = &loc_name_s; zval* arr = NULL; HashTable* hash_arr = NULL; @@ -1083,7 +1081,7 @@ static int add_array_entry(const char* loc_name, zval* hash_arr, char* key_name) } /* Over-allocates a few bytes for the integer so we don't have to reallocate. */ size_t cur_key_name_size = (sizeof("-2147483648") - 1) + strlen(key_name) + 1; - cur_key_name = emalloc(cur_key_name_size); + cur_key_name = reinterpret_cast(emalloc(cur_key_name_size)); snprintf( cur_key_name, cur_key_name_size , "%s%d", key_name , cnt++); add_assoc_string( hash_arr, cur_key_name , token); /* tokenize on the "_" or "-" and stop at singleton if any */ @@ -1117,7 +1115,7 @@ static int add_array_entry(const char* loc_name, zval* hash_arr, char* key_name) /* }}} */ /* {{{ parses a locale-id into an array the different parts of it */ -PHP_FUNCTION(locale_parse) +U_CFUNC PHP_FUNCTION(locale_parse) { char* loc_name = NULL; size_t loc_name_len = 0; @@ -1153,7 +1151,7 @@ PHP_FUNCTION(locale_parse) /* }}} */ /* {{{ gets an array containing the list of variants, or null */ -PHP_FUNCTION(locale_get_all_variants) +U_CFUNC PHP_FUNCTION(locale_get_all_variants) { char* loc_name = NULL; size_t loc_name_len = 0; @@ -1237,7 +1235,7 @@ static int strToMatch(const char* str ,char *retstr) /* {{{ Checks if a $langtag filter matches with $locale according to RFC 4647's basic filtering algorithm */ /* }}} */ /* {{{ Checks if a $langtag filter matches with $locale according to RFC 4647's basic filtering algorithm */ -PHP_FUNCTION(locale_filter_matches) +U_CFUNC PHP_FUNCTION(locale_filter_matches) { char* lang_tag = NULL; size_t lang_tag_len = 0; @@ -1282,21 +1280,19 @@ PHP_FUNCTION(locale_filter_matches) /* canonicalize loc_range */ can_loc_range=get_icu_value_internal( loc_range , LOC_CANONICALIZE_TAG , &result , 0); if( result <=0) { - intl_error_set( NULL, status, - "locale_filter_matches : unable to canonicalize loc_range" , 0 ); + intl_error_set(NULL, status, "unable to canonicalize loc_range"); RETURN_FALSE; } /* canonicalize lang_tag */ can_lang_tag = get_icu_value_internal( lang_tag , LOC_CANONICALIZE_TAG , &result , 0); if( result <=0) { - intl_error_set( NULL, status, - "locale_filter_matches : unable to canonicalize lang_tag" , 0 ); + intl_error_set(NULL, status, "unable to canonicalize lang_tag"); RETURN_FALSE; } /* Convert to lower case for case-insensitive comparison */ - cur_lang_tag = ecalloc( 1, can_lang_tag->len + 1); + cur_lang_tag = reinterpret_cast(ecalloc( 1, can_lang_tag->len + 1)); /* Convert to lower case for case-insensitive comparison */ result = strToMatch( can_lang_tag->val , cur_lang_tag); @@ -1306,7 +1302,7 @@ PHP_FUNCTION(locale_filter_matches) RETURN_FALSE; } - cur_loc_range = ecalloc( 1, can_loc_range->len + 1); + cur_loc_range = reinterpret_cast(ecalloc( 1, can_loc_range->len + 1)); result = strToMatch( can_loc_range->val , cur_loc_range ); if( result == 0) { efree( cur_lang_tag ); @@ -1353,14 +1349,14 @@ PHP_FUNCTION(locale_filter_matches) } /* end of if isCanonical */ else{ /* Convert to lower case for case-insensitive comparison */ - cur_lang_tag = ecalloc( 1, strlen(lang_tag ) + 1); + cur_lang_tag = reinterpret_cast(ecalloc( 1, strlen(lang_tag ) + 1)); result = strToMatch( lang_tag , cur_lang_tag); if( result == 0) { efree( cur_lang_tag ); RETURN_FALSE; } - cur_loc_range = ecalloc( 1, strlen(loc_range ) + 1); + cur_loc_range = reinterpret_cast(ecalloc( 1, strlen(loc_range ) + 1)); result = strToMatch( loc_range , cur_loc_range ); if( result == 0) { efree( cur_lang_tag ); @@ -1425,7 +1421,7 @@ static zend_string* lookup_loc_range(const char* loc_range, HashTable* hash_arr, zend_string* return_value = NULL; - char **cur_arr = ecalloc(zend_hash_num_elements(hash_arr)*2, sizeof(char *)); + char **cur_arr = reinterpret_cast(ecalloc(zend_hash_num_elements(hash_arr)*2, sizeof(char *))); ZEND_HASH_FOREACH_VAL(hash_arr, ele_value) { ZVAL_DEREF(ele_value); /* convert the array to lowercase , also replace hyphens with the underscore and store it in cur_arr */ @@ -1441,7 +1437,7 @@ static zend_string* lookup_loc_range(const char* loc_range, HashTable* hash_arr, cur_arr[cur_arr_len*2] = estrndup(Z_STRVAL_P(ele_value), Z_STRLEN_P(ele_value)); result = strToMatch(Z_STRVAL_P(ele_value), cur_arr[cur_arr_len*2]); if(result == 0) { - intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "lookup_loc_range: unable to canonicalize lang_tag", 0); + intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "unable to canonicalize lang_tag"); LOOKUP_CLEAN_RETURN(NULL); } cur_arr[cur_arr_len*2+1] = Z_STRVAL_P(ele_value); @@ -1456,14 +1452,14 @@ static zend_string* lookup_loc_range(const char* loc_range, HashTable* hash_arr, if(lang_tag) { zend_string_release_ex(lang_tag, 0); } - intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "lookup_loc_range: unable to canonicalize lang_tag" , 0); + intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "unable to canonicalize lang_tag"); LOOKUP_CLEAN_RETURN(NULL); } - cur_arr[i*2] = erealloc(cur_arr[i*2], lang_tag->len+1); + cur_arr[i*2] = reinterpret_cast(erealloc(cur_arr[i*2], lang_tag->len+1)); result = strToMatch(lang_tag->val, cur_arr[i*2]); zend_string_release_ex(lang_tag, 0); if(result == 0) { - intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "lookup_loc_range: unable to canonicalize lang_tag" , 0); + intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "unable to canonicalize lang_tag"); LOOKUP_CLEAN_RETURN(NULL); } } @@ -1475,7 +1471,7 @@ static zend_string* lookup_loc_range(const char* loc_range, HashTable* hash_arr, can_loc_range = get_icu_value_internal(loc_range, LOC_CANONICALIZE_TAG, &result , 0); if( result != 1 || can_loc_range == NULL || !can_loc_range->val[0]) { /* Error */ - intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "lookup_loc_range: unable to canonicalize loc_range" , 0 ); + intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "unable to canonicalize loc_range"); if(can_loc_range) { zend_string_release_ex(can_loc_range, 0); } @@ -1485,7 +1481,7 @@ static zend_string* lookup_loc_range(const char* loc_range, HashTable* hash_arr, } } - cur_loc_range = ecalloc(1, strlen(loc_range)+1); + cur_loc_range = reinterpret_cast(ecalloc(1, strlen(loc_range)+1)); /* convert to lower and replace hyphens */ result = strToMatch(loc_range, cur_loc_range); if(can_loc_range) { @@ -1493,7 +1489,7 @@ static zend_string* lookup_loc_range(const char* loc_range, HashTable* hash_arr, } if(result == 0) { efree(cur_loc_range); - intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "lookup_loc_range: unable to canonicalize lang_tag" , 0); + intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "unable to canonicalize lang_tag"); LOOKUP_CLEAN_RETURN(NULL); } @@ -1525,7 +1521,7 @@ static zend_string* lookup_loc_range(const char* loc_range, HashTable* hash_arr, /* {{{ Searches the items in $langtag for the best match to the language * range */ -PHP_FUNCTION(locale_lookup) +U_CFUNC PHP_FUNCTION(locale_lookup) { zend_string* fallback_loc_str = NULL; char* loc_range = NULL; @@ -1580,12 +1576,12 @@ PHP_FUNCTION(locale_lookup) /* {{{ Tries to find out best available locale based on HTTP "Accept-Language" header */ /* }}} */ /* {{{ Tries to find out best available locale based on HTTP "Accept-Language" header */ -PHP_FUNCTION(locale_accept_from_http) +U_CFUNC PHP_FUNCTION(locale_accept_from_http) { UEnumeration *available; char *http_accept = NULL; size_t http_accept_len; - UErrorCode status = 0; + UErrorCode status = U_ZERO_ERROR; int len; char resultLocale[INTL_MAX_LOCALE_LEN+1]; UAcceptResult outResult; @@ -1603,7 +1599,7 @@ PHP_FUNCTION(locale_accept_from_http) len = end ? end-start : http_accept_len-(start-http_accept); if(len > ULOC_FULLNAME_CAPACITY) { intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, - "locale_accept_from_http: locale string too long", 0 ); + "locale string too long"); RETURN_FALSE; } if(end) { @@ -1613,11 +1609,11 @@ PHP_FUNCTION(locale_accept_from_http) } available = ures_openAvailableLocales(NULL, &status); - INTL_CHECK_STATUS(status, "locale_accept_from_http: failed to retrieve locale list"); + INTL_CHECK_STATUS(status, "failed to retrieve locale list"); len = uloc_acceptLanguageFromHTTP(resultLocale, INTL_MAX_LOCALE_LEN, &outResult, http_accept, available, &status); uenum_close(available); - INTL_CHECK_STATUS(status, "locale_accept_from_http: failed to find acceptable locale"); + INTL_CHECK_STATUS(status, "failed to find acceptable locale"); if (len < 0 || outResult == ULOC_ACCEPT_FAILED) { RETURN_FALSE; } @@ -1625,7 +1621,7 @@ PHP_FUNCTION(locale_accept_from_http) } /* }}} */ -PHP_FUNCTION(locale_is_right_to_left) +U_CFUNC PHP_FUNCTION(locale_is_right_to_left) { char *locale; size_t locale_len; @@ -1641,10 +1637,10 @@ PHP_FUNCTION(locale_is_right_to_left) RETURN_BOOL(uloc_isRightToLeft(locale)); } -PHP_FUNCTION(locale_add_likely_subtags) +U_CFUNC PHP_FUNCTION(locale_add_likely_subtags) { char *locale, maximized_locale[ULOC_FULLNAME_CAPACITY]; - UErrorCode status = 0; + UErrorCode status = U_ZERO_ERROR; size_t locale_len; ZEND_PARSE_PARAMETERS_START(1, 1) @@ -1656,7 +1652,7 @@ PHP_FUNCTION(locale_add_likely_subtags) } int32_t maximized_locale_len = uloc_addLikelySubtags(locale, maximized_locale, sizeof(maximized_locale), &status); - INTL_CHECK_STATUS(status, "locale_add_likely_subtags: invalid locale"); + INTL_CHECK_STATUS(status, "invalid locale"); if (maximized_locale_len < 0) { RETURN_FALSE; } @@ -1664,10 +1660,10 @@ PHP_FUNCTION(locale_add_likely_subtags) RETURN_STRINGL(maximized_locale, maximized_locale_len); } -PHP_FUNCTION(locale_minimize_subtags) +U_CFUNC PHP_FUNCTION(locale_minimize_subtags) { char *locale, minimized_locale[ULOC_FULLNAME_CAPACITY]; - UErrorCode status = 0; + UErrorCode status = U_ZERO_ERROR; size_t locale_len; ZEND_PARSE_PARAMETERS_START(1, 1) @@ -1679,7 +1675,7 @@ PHP_FUNCTION(locale_minimize_subtags) } int32_t minimized_locale_len = uloc_minimizeSubtags(locale, minimized_locale, sizeof(minimized_locale), &status); - INTL_CHECK_STATUS(status, "locale_minimize_subtags: invalid locale"); + INTL_CHECK_STATUS(status, "invalid locale"); if (minimized_locale_len < 0) { RETURN_FALSE; } diff --git a/ext/intl/msgformat/msgformat.c b/ext/intl/msgformat/msgformat.cpp similarity index 77% rename from ext/intl/msgformat/msgformat.c rename to ext/intl/msgformat/msgformat.cpp index 51643d86d45..a9e1f71bfc6 100644 --- a/ext/intl/msgformat/msgformat.c +++ b/ext/intl/msgformat/msgformat.cpp @@ -19,13 +19,15 @@ #include #include +extern "C" { #include "php_intl.h" #include "msgformat_class.h" #include "msgformat_data.h" #include "intl_convert.h" +} /* {{{ */ -static int msgfmt_ctor(INTERNAL_FUNCTION_PARAMETERS, zend_error_handling *error_handling, bool *error_handling_replaced) +static int msgfmt_ctor(INTERNAL_FUNCTION_PARAMETERS) { char* locale; char* pattern; @@ -43,18 +45,13 @@ static int msgfmt_ctor(INTERNAL_FUNCTION_PARAMETERS, zend_error_handling *error_ Z_PARAM_STRING(pattern, pattern_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; - } - INTL_CHECK_LOCALE_LEN_OR_FAILURE(locale_len); MSG_FORMAT_METHOD_FETCH_OBJECT_NO_CHECK; /* Convert pattern (if specified) to UTF-16. */ if(pattern && pattern_len) { intl_convert_utf8_to_utf16(&spattern, &spattern_len, pattern, pattern_len, &INTL_DATA_ERROR_CODE(mfo)); - INTL_CTOR_CHECK_STATUS(mfo, "msgfmt_create: error converting pattern to UTF-16"); + INTL_CTOR_CHECK_STATUS(mfo, "error converting pattern to UTF-16"); } else { spattern_len = 0; spattern = NULL; @@ -92,22 +89,22 @@ static int msgfmt_ctor(INTERNAL_FUNCTION_PARAMETERS, zend_error_handling *error_ smart_str_free( &parse_error_str ); intl_error_set_code( NULL, INTL_DATA_ERROR_CODE( mfo ) ); - intl_errors_set_custom_msg( INTL_DATA_ERROR_P( mfo ), msg, 1 ); + intl_errors_set_custom_msg( INTL_DATA_ERROR_P( mfo ), msg); efree( msg ); return FAILURE; } - INTL_CTOR_CHECK_STATUS(mfo, "msgfmt_create: message formatter creation failed"); + INTL_CTOR_CHECK_STATUS(mfo, "message formatter creation failed"); return SUCCESS; } /* }}} */ /* {{{ Create formatter. */ -PHP_FUNCTION( msgfmt_create ) +U_CFUNC PHP_FUNCTION( msgfmt_create ) { object_init_ex( return_value, MessageFormatter_ce_ptr ); - if (msgfmt_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, NULL, NULL) == FAILURE) { + if (msgfmt_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU) == FAILURE) { zval_ptr_dtor(return_value); RETURN_NULL(); } @@ -115,27 +112,24 @@ PHP_FUNCTION( msgfmt_create ) /* }}} */ /* {{{ MessageFormatter object constructor. */ -PHP_METHOD( MessageFormatter, __construct ) +U_CFUNC PHP_METHOD( MessageFormatter, __construct ) { - zend_error_handling error_handling; - bool error_handling_replaced = 0; + const bool old_use_exception = INTL_G(use_exceptions); + const zend_long old_error_level = INTL_G(error_level); + INTL_G(use_exceptions) = true; + INTL_G(error_level) = 0; return_value = ZEND_THIS; - 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); - } - } - if (error_handling_replaced) { - zend_restore_error_handling(&error_handling); + if (msgfmt_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU) == FAILURE) { + ZEND_ASSERT(EG(exception)); } + INTL_G(use_exceptions) = old_use_exception; + INTL_G(error_level) = old_error_level; } /* }}} */ /* {{{ Get formatter's last error code. */ -PHP_FUNCTION( msgfmt_get_error_code ) +U_CFUNC PHP_FUNCTION( msgfmt_get_error_code ) { zval* object = NULL; MessageFormatter_object* mfo = NULL; @@ -155,7 +149,7 @@ PHP_FUNCTION( msgfmt_get_error_code ) /* }}} */ /* {{{ Get text description for formatter's last error code. */ -PHP_FUNCTION( msgfmt_get_error_message ) +U_CFUNC PHP_FUNCTION( msgfmt_get_error_message ) { zend_string* message = NULL; zval* object = NULL; diff --git a/ext/intl/msgformat/msgformat_attr.c b/ext/intl/msgformat/msgformat_attr.cpp similarity index 94% rename from ext/intl/msgformat/msgformat_attr.c rename to ext/intl/msgformat/msgformat_attr.cpp index b56bf360d11..e7ec006e5e7 100644 --- a/ext/intl/msgformat/msgformat_attr.c +++ b/ext/intl/msgformat/msgformat_attr.cpp @@ -16,15 +16,17 @@ #include #endif +extern "C" { #include "php_intl.h" #include "msgformat_class.h" #include "msgformat_data.h" #include "intl_convert.h" +} #include /* {{{ Get formatter pattern. */ -PHP_FUNCTION( msgfmt_get_pattern ) +U_CFUNC PHP_FUNCTION( msgfmt_get_pattern ) { MSG_FORMAT_METHOD_INIT_VARS; @@ -46,7 +48,7 @@ PHP_FUNCTION( msgfmt_get_pattern ) /* }}} */ /* {{{ Set formatter pattern. */ -PHP_FUNCTION( msgfmt_set_pattern ) +U_CFUNC PHP_FUNCTION( msgfmt_set_pattern ) { char* value = NULL; size_t value_len = 0; @@ -83,7 +85,7 @@ PHP_FUNCTION( msgfmt_set_pattern ) if (U_FAILURE(INTL_DATA_ERROR_CODE(mfo))) { char *msg; spprintf(&msg, 0, "Error setting symbol value at line %d, offset %d", spattern_error.line, spattern_error.offset); - intl_errors_set_custom_msg(INTL_DATA_ERROR_P(mfo), msg, 1); + intl_errors_set_custom_msg(INTL_DATA_ERROR_P(mfo), msg); efree(msg); RETURN_FALSE; } @@ -105,7 +107,7 @@ PHP_FUNCTION( msgfmt_set_pattern ) /* }}} */ /* {{{ Get formatter locale. */ -PHP_FUNCTION( msgfmt_get_locale ) +U_CFUNC PHP_FUNCTION( msgfmt_get_locale ) { char *loc; MSG_FORMAT_METHOD_INIT_VARS; diff --git a/ext/intl/msgformat/msgformat_class.c b/ext/intl/msgformat/msgformat_class.cpp similarity index 87% rename from ext/intl/msgformat/msgformat_class.c rename to ext/intl/msgformat/msgformat_class.cpp index 4e0766a911b..e762febf0d1 100644 --- a/ext/intl/msgformat/msgformat_class.c +++ b/ext/intl/msgformat/msgformat_class.cpp @@ -14,10 +14,12 @@ #include +extern "C" { #include "msgformat_class.h" #include "php_intl.h" #include "msgformat_data.h" #include "msgformat_arginfo.h" +} #include @@ -29,7 +31,7 @@ static zend_object_handlers MessageFormatter_handlers; */ /* {{{ MessageFormatter_objects_free */ -void MessageFormatter_object_free( zend_object *object ) +U_CFUNC void MessageFormatter_object_free( zend_object *object ) { MessageFormatter_object* mfo = php_intl_messageformatter_fetch_object(object); @@ -40,11 +42,11 @@ void MessageFormatter_object_free( zend_object *object ) /* }}} */ /* {{{ MessageFormatter_object_create */ -zend_object *MessageFormatter_object_create(zend_class_entry *ce) +U_CFUNC zend_object *MessageFormatter_object_create(zend_class_entry *ce) { MessageFormatter_object* intern; - intern = zend_object_alloc(sizeof(MessageFormatter_object), ce); + intern = reinterpret_cast(zend_object_alloc(sizeof(MessageFormatter_object), ce)); msgformat_data_init( &intern->mf_data ); zend_object_std_init( &intern->zo, ce ); object_properties_init(&intern->zo, ce); @@ -54,7 +56,7 @@ zend_object *MessageFormatter_object_create(zend_class_entry *ce) /* }}} */ /* {{{ MessageFormatter_object_clone */ -zend_object *MessageFormatter_object_clone(zend_object *object) +U_CFUNC zend_object *MessageFormatter_object_clone(zend_object *object) { MessageFormatter_object *mfo = php_intl_messageformatter_fetch_object(object); zend_object *new_obj = MessageFormatter_ce_ptr->create_object(object->ce); @@ -66,7 +68,7 @@ zend_object *MessageFormatter_object_clone(zend_object *object) /* clone formatter object */ if (MSG_FORMAT_OBJECT(mfo) != NULL) { UErrorCode error = U_ZERO_ERROR; - MSG_FORMAT_OBJECT(new_mfo) = umsg_clone(MSG_FORMAT_OBJECT(mfo), &error); + MSG_FORMAT_OBJECT(new_mfo) = reinterpret_cast(umsg_clone(MSG_FORMAT_OBJECT(mfo), &error)); if (U_FAILURE(error)) { zend_throw_error(NULL, "Failed to clone MessageFormatter"); diff --git a/ext/intl/msgformat/msgformat_data.c b/ext/intl/msgformat/msgformat_data.cpp similarity index 92% rename from ext/intl/msgformat/msgformat_data.c rename to ext/intl/msgformat/msgformat_data.cpp index 5d170d25945..f8b7ec39601 100644 --- a/ext/intl/msgformat/msgformat_data.c +++ b/ext/intl/msgformat/msgformat_data.cpp @@ -24,7 +24,7 @@ /* {{{ void msgformat_data_init( msgformat_data* mf_data ) * Initialize internals of msgformat_data. */ -void msgformat_data_init( msgformat_data* mf_data ) +U_CFUNC void msgformat_data_init( msgformat_data* mf_data ) { if( !mf_data ) return; @@ -40,7 +40,7 @@ void msgformat_data_init( msgformat_data* mf_data ) /* {{{ void msgformat_data_free( msgformat_data* mf_data ) * Clean up memory allocated for msgformat_data */ -void msgformat_data_free(msgformat_data* mf_data) +U_CFUNC void msgformat_data_free(msgformat_data* mf_data) { if (!mf_data) return; @@ -69,7 +69,7 @@ void msgformat_data_free(msgformat_data* mf_data) */ msgformat_data* msgformat_data_create( void ) { - msgformat_data* mf_data = ecalloc( 1, sizeof(msgformat_data) ); + msgformat_data* mf_data = reinterpret_cast(ecalloc( 1, sizeof(msgformat_data) )); msgformat_data_init( mf_data ); diff --git a/ext/intl/msgformat/msgformat_data.h b/ext/intl/msgformat/msgformat_data.h index 539c7d6d925..bac94cbec34 100644 --- a/ext/intl/msgformat/msgformat_data.h +++ b/ext/intl/msgformat/msgformat_data.h @@ -17,7 +17,13 @@ #include +#ifdef __cplusplus +extern "C" { +#endif #include "../intl_error.h" +#ifdef __cplusplus +} +#endif #include @@ -26,16 +32,22 @@ typedef struct { intl_error error; // formatter handling - UMessageFormat* umsgf; + UMessageFormat *umsgf; char* orig_format; zend_ulong orig_format_len; HashTable* arg_types; int tz_set; /* if we've already the time zone in sub-formats */ } msgformat_data; +#ifdef __cplusplus +extern "C" { +#endif msgformat_data* msgformat_data_create( void ); void msgformat_data_init( msgformat_data* mf_data ); void msgformat_data_free( msgformat_data* mf_data ); +#ifdef __cplusplus +} +#endif #ifdef MSG_FORMAT_QUOTE_APOS int msgformat_fix_quotes(UChar **spattern, uint32_t *spattern_len, UErrorCode *ec); diff --git a/ext/intl/msgformat/msgformat_format.c b/ext/intl/msgformat/msgformat_format.cpp similarity index 94% rename from ext/intl/msgformat/msgformat_format.c rename to ext/intl/msgformat/msgformat_format.cpp index 46a364c5d3a..8e3ec28b389 100644 --- a/ext/intl/msgformat/msgformat_format.c +++ b/ext/intl/msgformat/msgformat_format.cpp @@ -18,11 +18,13 @@ #include +extern "C" { #include "php_intl.h" #include "msgformat_class.h" #include "msgformat_data.h" #include "msgformat_helpers.h" #include "intl_convert.h" +} #ifndef Z_ADDREF_P #define Z_ADDREF_P(z) ((z)->refcount++) @@ -48,7 +50,7 @@ static void msgfmt_do_format(MessageFormatter_object *mfo, zval *args, zval *ret /* }}} */ /* {{{ Format a message. */ -PHP_FUNCTION( msgfmt_format ) +U_CFUNC PHP_FUNCTION( msgfmt_format ) { zval *args; MSG_FORMAT_METHOD_INIT_VARS; @@ -69,7 +71,7 @@ PHP_FUNCTION( msgfmt_format ) /* }}} */ /* {{{ Format a message. */ -PHP_FUNCTION( msgfmt_format_message ) +U_CFUNC PHP_FUNCTION( msgfmt_format_message ) { zval *args; UChar *spattern = NULL; @@ -99,7 +101,7 @@ PHP_FUNCTION( msgfmt_format_message ) if( U_FAILURE(INTL_DATA_ERROR_CODE((mfo))) ) { intl_error_set(/* intl_error* */ NULL, U_ILLEGAL_ARGUMENT_ERROR, - "msgfmt_format_message: error converting pattern to UTF-16", 0 ); + "error converting pattern to UTF-16"); RETURN_FALSE; } } else { @@ -114,7 +116,7 @@ PHP_FUNCTION( msgfmt_format_message ) #ifdef MSG_FORMAT_QUOTE_APOS if(msgformat_fix_quotes(&spattern, &spattern_len, &INTL_DATA_ERROR_CODE(mfo)) != SUCCESS) { intl_error_set(/* intl_error* */ NULL, U_INVALID_FORMAT_ERROR, - "msgfmt_format_message: error converting pattern to quote-friendly format", 0 ); + "msgfmt_format_message: error converting pattern to quote-friendly format"); RETURN_FALSE; } #endif @@ -136,11 +138,11 @@ PHP_FUNCTION( msgfmt_format_message ) /* Pass NULL to intl_error* parameter to store message in global Intl error msg stack */ intl_error_set_code(/* intl_error* */ NULL, INTL_DATA_ERROR_CODE( mfo ) ); - intl_errors_set_custom_msg(/* intl_error* */ NULL, msg, 1 ); + intl_errors_set_custom_msg(/* intl_error* */ NULL, msg); efree( msg ); } else { - intl_errors_set_custom_msg(/* intl_error* */ NULL, "Creating message formatter failed", 0 ); + intl_errors_set_custom_msg(/* intl_error* */ NULL, "Creating message formatter failed"); } umsg_close(MSG_FORMAT_OBJECT(mfo)); RETURN_FALSE; diff --git a/ext/intl/msgformat/msgformat_helpers.cpp b/ext/intl/msgformat/msgformat_helpers.cpp index fbd85b857f3..e734b2df27b 100644 --- a/ext/intl/msgformat/msgformat_helpers.cpp +++ b/ext/intl/msgformat/msgformat_helpers.cpp @@ -187,7 +187,7 @@ static HashTable *umsg_parse_format(MessageFormatter_object *mfo, int32_t argNumber = name_part.getValue(); if (argNumber < 0) { intl_errors_set(&err, U_INVALID_FORMAT_ERROR, - "Found part with negative number", 0); + "Found part with negative number"); continue; } if ((storedType = (Formattable::Type*)zend_hash_index_find_ptr(ret, (zend_ulong)argNumber)) == NULL) { @@ -196,7 +196,7 @@ static HashTable *umsg_parse_format(MessageFormatter_object *mfo, storedType = (Formattable::Type*)zend_hash_index_update_mem(ret, (zend_ulong)argNumber, (void*)&bogusType, sizeof(bogusType)); } } else { - intl_errors_set(&err, U_INVALID_FORMAT_ERROR, "Invalid part type encountered", 0); + intl_errors_set(&err, U_INVALID_FORMAT_ERROR, "Invalid part type encountered"); continue; } @@ -243,7 +243,7 @@ static HashTable *umsg_parse_format(MessageFormatter_object *mfo, * is broken. */ intl_errors_set(&err, U_PARSE_ERROR, "Expected UMSGPAT_PART_TYPE_ARG_TYPE part following " - "UMSGPAT_ARG_TYPE_SIMPLE part", 0); + "UMSGPAT_ARG_TYPE_SIMPLE part"); continue; } } else if (argType == UMSGPAT_ARG_TYPE_PLURAL) { @@ -262,7 +262,7 @@ static HashTable *umsg_parse_format(MessageFormatter_object *mfo, /* We found a different type for the same arg! */ if (*storedType != Formattable::kObject && *storedType != type) { intl_errors_set(&err, U_ARGUMENT_TYPE_MISMATCH, - "Inconsistent types declared for an argument", 0); + "Inconsistent types declared for an argument"); continue; } @@ -330,7 +330,7 @@ static void umsg_set_timezone(MessageFormatter_object *mfo, if (UNEXPECTED(formats == NULL)) { intl_errors_set(&err, U_MEMORY_ALLOCATION_ERROR, - "Out of memory retrieving subformats", 0); + "Out of memory retrieving subformats"); } for (int i = 0; U_SUCCESS(err.code) && i < count; i++) { @@ -341,9 +341,7 @@ static void umsg_set_timezone(MessageFormatter_object *mfo, } if (used_tz == NULL) { - zval nullzv; - ZVAL_NULL(&nullzv); - used_tz = timezone_process_timezone_argument(&nullzv, &err, "msgfmt_format"); + used_tz = timezone_process_timezone_argument(nullptr, nullptr, &err); if (used_tz == NULL) { continue; } @@ -405,7 +403,7 @@ U_CFUNC void umsg_format_helper(MessageFormatter_object *mfo, /* includes case where index < 0 because it's exposed as unsigned */ if (UNEXPECTED(num_index > (zend_ulong)INT32_MAX)) { intl_errors_set(&err, U_ILLEGAL_ARGUMENT_ERROR, - "Found negative or too large array key", 0); + "Found negative or too large array key"); continue; } @@ -421,7 +419,7 @@ U_CFUNC void umsg_format_helper(MessageFormatter_object *mfo, char *message; spprintf(&message, 0, "Invalid UTF-8 data in argument key: '%s'", ZSTR_VAL(str_index)); - intl_errors_set(&err, err.code, message, 1); + intl_errors_set(&err, err.code, message); efree(message); continue; } @@ -457,7 +455,7 @@ U_CFUNC void umsg_format_helper(MessageFormatter_object *mfo, char *message; spprintf(&message, 0, "Invalid UTF-8 data in string argument: " "'%s'", ZSTR_VAL(str)); - intl_errors_set(&err, err.code, message, 1); + intl_errors_set(&err, err.code, message); efree(message); delete text; continue; @@ -481,7 +479,7 @@ U_CFUNC void umsg_format_helper(MessageFormatter_object *mfo, Z_DVAL_P(elem) < (double)INT32_MIN)) { intl_errors_set(&err, U_ILLEGAL_ARGUMENT_ERROR, "Found PHP float with absolute value too large for " - "32 bit integer argument", 0); + "32 bit integer argument"); } else { tInt32 = (int32_t)Z_DVAL_P(elem); } @@ -490,7 +488,7 @@ U_CFUNC void umsg_format_helper(MessageFormatter_object *mfo, Z_LVAL_P(elem) < INT32_MIN)) { intl_errors_set(&err, U_ILLEGAL_ARGUMENT_ERROR, "Found PHP integer with absolute value too large " - "for 32 bit integer argument", 0); + "for 32 bit integer argument"); } else { tInt32 = (int32_t)Z_LVAL_P(elem); } @@ -509,7 +507,7 @@ U_CFUNC void umsg_format_helper(MessageFormatter_object *mfo, Z_DVAL_P(elem) < (double)U_INT64_MIN)) { intl_errors_set(&err, U_ILLEGAL_ARGUMENT_ERROR, "Found PHP float with absolute value too large for " - "64 bit integer argument", 0); + "64 bit integer argument"); } else { tInt64 = (int64_t)Z_DVAL_P(elem); } @@ -524,7 +522,7 @@ U_CFUNC void umsg_format_helper(MessageFormatter_object *mfo, } case Formattable::kDate: { - double dd = intl_zval_to_millis(elem, &err, "msgfmt_format"); + double dd = intl_zval_to_millis(elem, &err); if (U_FAILURE(err.code)) { char *message; zend_string *u8key; @@ -533,7 +531,7 @@ U_CFUNC void umsg_format_helper(MessageFormatter_object *mfo, if (u8key) { spprintf(&message, 0, "The argument for key '%s' " "cannot be used as a date or time", ZSTR_VAL(u8key)); - intl_errors_set(&err, err.code, message, 1); + intl_errors_set(&err, err.code, message); zend_string_release_ex(u8key, 0); efree(message); } @@ -544,7 +542,7 @@ U_CFUNC void umsg_format_helper(MessageFormatter_object *mfo, } default: intl_errors_set(&err, U_ILLEGAL_ARGUMENT_ERROR, - "Found unsupported argument type", 0); + "Found unsupported argument type"); break; } } else { @@ -578,8 +576,7 @@ U_CFUNC void umsg_format_helper(MessageFormatter_object *mfo, spprintf(&message, 0, "No strategy to convert the " "value given for the argument with key '%s' " "is available", ZSTR_VAL(u8key)); - intl_errors_set(&err, - U_ILLEGAL_ARGUMENT_ERROR, message, 1); + intl_errors_set(&err, U_ILLEGAL_ARGUMENT_ERROR, message); zend_string_release_ex(u8key, 0); efree(message); } @@ -602,7 +599,7 @@ U_CFUNC void umsg_format_helper(MessageFormatter_object *mfo, if (U_FAILURE(err.code)) { intl_errors_set(&err, err.code, - "Call to ICU MessageFormat::format() has failed", 0); + "Call to ICU MessageFormat::format() has failed"); return; } @@ -610,8 +607,7 @@ U_CFUNC void umsg_format_helper(MessageFormatter_object *mfo, *formatted = eumalloc(*formatted_len+1); resultStr.extract(*formatted, *formatted_len+1, err.code); if (U_FAILURE(err.code)) { - intl_errors_set(&err, err.code, - "Error copying format() result", 0); + intl_errors_set(&err, err.code, "Error copying format() result"); return; } } diff --git a/ext/intl/msgformat/msgformat_parse.c b/ext/intl/msgformat/msgformat_parse.cpp similarity index 94% rename from ext/intl/msgformat/msgformat_parse.c rename to ext/intl/msgformat/msgformat_parse.cpp index 80ede995c42..28d7ce71080 100644 --- a/ext/intl/msgformat/msgformat_parse.c +++ b/ext/intl/msgformat/msgformat_parse.cpp @@ -18,11 +18,13 @@ #include +extern "C" { #include "php_intl.h" #include "msgformat_class.h" #include "msgformat_data.h" #include "msgformat_helpers.h" #include "intl_convert.h" +} /* {{{ */ static void msgfmt_do_parse(MessageFormatter_object *mfo, char *source, size_t src_len, zval *return_value) @@ -52,7 +54,7 @@ static void msgfmt_do_parse(MessageFormatter_object *mfo, char *source, size_t s /* }}} */ /* {{{ Parse a message */ -PHP_FUNCTION( msgfmt_parse ) +U_CFUNC PHP_FUNCTION( msgfmt_parse ) { char *source; size_t source_len; @@ -74,7 +76,7 @@ PHP_FUNCTION( msgfmt_parse ) /* }}} */ /* {{{ Parse a message. */ -PHP_FUNCTION( msgfmt_parse_message ) +U_CFUNC PHP_FUNCTION( msgfmt_parse_message ) { UChar *spattern = NULL; int spattern_len = 0; @@ -102,7 +104,7 @@ PHP_FUNCTION( msgfmt_parse_message ) if( U_FAILURE(INTL_DATA_ERROR_CODE((mfo))) ) { intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, - "msgfmt_parse_message: error converting pattern to UTF-16", 0 ); + "error converting pattern to UTF-16"); RETURN_FALSE; } } else { @@ -127,10 +129,11 @@ PHP_FUNCTION( msgfmt_parse_message ) if(spattern && spattern_len) { efree(spattern); } - INTL_METHOD_CHECK_STATUS(mfo, "Creating message formatter failed"); + INTL_METHOD_CHECK_STATUS_OR_GOTO(mfo, "Creating message formatter failed", clean); msgfmt_do_parse(mfo, source, src_len, return_value); +clean: /* drop the temporary formatter */ msgformat_data_free(&mfo->mf_data); } diff --git a/ext/intl/normalizer/normalizer_class.c b/ext/intl/normalizer/normalizer_class.cpp similarity index 86% rename from ext/intl/normalizer/normalizer_class.c rename to ext/intl/normalizer/normalizer_class.cpp index d9e413d5e51..3838f754632 100644 --- a/ext/intl/normalizer/normalizer_class.c +++ b/ext/intl/normalizer/normalizer_class.cpp @@ -12,11 +12,22 @@ +----------------------------------------------------------------------+ */ +#if __cplusplus >= 201703L +#include +#endif +#include + #include "normalizer.h" #include "normalizer_class.h" #include "php_intl.h" +#ifdef __cplusplus +extern "C" { +#endif #include "normalizer_arginfo.h" #include "intl_error.h" +#ifdef __cplusplus +} +#endif #include @@ -29,7 +40,7 @@ zend_class_entry *Normalizer_ce_ptr = NULL; /* {{{ normalizer_register_Normalizer_class * Initialize 'Normalizer' class */ -void normalizer_register_Normalizer_class( void ) +U_CFUNC void normalizer_register_Normalizer_class( void ) { /* Create and register 'Normalizer' class. */ Normalizer_ce_ptr = register_class_Normalizer(); diff --git a/ext/intl/normalizer/normalizer_class.h b/ext/intl/normalizer/normalizer_class.h index 6e57cae40ba..8f88f215abc 100644 --- a/ext/intl/normalizer/normalizer_class.h +++ b/ext/intl/normalizer/normalizer_class.h @@ -36,6 +36,12 @@ typedef struct { #define NORMALIZER_ERROR_CODE(co) INTL_ERROR_CODE(NORMALIZER_ERROR(co)) #define NORMALIZER_ERROR_CODE_P(co) &(INTL_ERROR_CODE(NORMALIZER_ERROR(co))) +#ifdef __cplusplus +extern "C" { +#endif void normalizer_register_Normalizer_class( void ); +#ifdef __cplusplus +} +#endif extern zend_class_entry *Normalizer_ce_ptr; #endif // #ifndef NORMALIZER_CLASS_H diff --git a/ext/intl/normalizer/normalizer_normalize.c b/ext/intl/normalizer/normalizer_normalize.cpp similarity index 93% rename from ext/intl/normalizer/normalizer_normalize.c rename to ext/intl/normalizer/normalizer_normalize.cpp index 38f12134146..92e8f1166ad 100644 --- a/ext/intl/normalizer/normalizer_normalize.c +++ b/ext/intl/normalizer/normalizer_normalize.cpp @@ -16,11 +16,18 @@ #include #endif +#if __cplusplus >= 201703L +#include +#include +#endif + +extern "C" { #include "php_intl.h" #include #include "normalizer.h" #include "normalizer_class.h" #include "intl_convert.h" +} #include @@ -71,7 +78,7 @@ static UBool intl_is_normalized(zend_long form, const UChar *uinput, int32_t uin }/*}}}*/ /* {{{ Normalize a string. */ -PHP_FUNCTION( normalizer_normalize ) +U_CFUNC PHP_FUNCTION( normalizer_normalize ) { char* input = NULL; /* form is optional, defaults to FORM_C */ @@ -130,7 +137,7 @@ PHP_FUNCTION( normalizer_normalize ) intl_error_set_code( NULL, status ); /* Set error messages. */ - intl_error_set_custom_msg( NULL, "Error converting input string to UTF-16", 0 ); + intl_error_set_custom_msg( NULL, "Error converting input string to UTF-16"); if (uinput) { efree( uinput ); } @@ -150,7 +157,7 @@ PHP_FUNCTION( normalizer_normalize ) * (U_STRING_NOT_TERMINATED_WARNING usually means that the input string is empty). */ if( U_FAILURE(status) && status != U_BUFFER_OVERFLOW_ERROR && status != U_STRING_NOT_TERMINATED_WARNING ) { - intl_error_set_custom_msg( NULL, "Error normalizing string", 0 ); + intl_error_set_custom_msg( NULL, "Error normalizing string"); efree( uret_buf ); efree( uinput ); RETURN_FALSE; @@ -172,7 +179,7 @@ PHP_FUNCTION( normalizer_normalize ) /* Bail out if an unexpected error occurred. */ if( U_FAILURE(status) ) { /* Set error messages. */ - intl_error_set_custom_msg( NULL,"Error normalizing string", 0 ); + intl_error_set_custom_msg( NULL,"Error normalizing string"); efree( uret_buf ); efree( uinput ); RETURN_FALSE; @@ -190,7 +197,7 @@ PHP_FUNCTION( normalizer_normalize ) if( !u8str ) { intl_error_set( NULL, status, - "normalizer_normalize: error converting normalized text UTF-8", 0 ); + "error converting normalized text UTF-8"); RETURN_FALSE; } @@ -200,7 +207,7 @@ PHP_FUNCTION( normalizer_normalize ) /* }}} */ /* {{{ Test if a string is in a given normalization form. */ -PHP_FUNCTION( normalizer_is_normalized ) +U_CFUNC PHP_FUNCTION( normalizer_is_normalized ) { char* input = NULL; /* form is optional, defaults to FORM_C */ @@ -248,7 +255,7 @@ PHP_FUNCTION( normalizer_is_normalized ) intl_error_set_code( NULL, status ); /* Set error messages. */ - intl_error_set_custom_msg( NULL, "Error converting string to UTF-16.", 0 ); + intl_error_set_custom_msg( NULL, "Error converting string to UTF-16."); if (uinput) { efree( uinput ); } @@ -264,7 +271,7 @@ PHP_FUNCTION( normalizer_is_normalized ) /* Bail out if an unexpected error occurred. */ if( U_FAILURE(status) ) { /* Set error messages. */ - intl_error_set_custom_msg( NULL,"Error testing if string is the given normalization form.", 0 ); + intl_error_set_custom_msg( NULL,"Error testing if string is the given normalization form."); RETURN_FALSE; } @@ -276,7 +283,7 @@ PHP_FUNCTION( normalizer_is_normalized ) /* }}} */ /* {{{ Returns the Decomposition_Mapping property for the given UTF-8 encoded code point. */ -PHP_FUNCTION( normalizer_get_raw_decomposition ) +U_CFUNC PHP_FUNCTION( normalizer_get_raw_decomposition ) { char* input = NULL; size_t input_length = 0; @@ -304,13 +311,13 @@ PHP_FUNCTION( normalizer_get_raw_decomposition ) U8_NEXT(input, offset, input_length, codepoint); if ((size_t)offset != input_length) { intl_error_set_code(NULL, U_ILLEGAL_ARGUMENT_ERROR); - intl_error_set_custom_msg(NULL, "Input string must be exactly one UTF-8 encoded code point long.", 0); + intl_error_set_custom_msg(NULL, "Input string must be exactly one UTF-8 encoded code point long."); return; } if ((codepoint < UCHAR_MIN_VALUE) || (codepoint > UCHAR_MAX_VALUE)) { intl_error_set_code(NULL, U_ILLEGAL_ARGUMENT_ERROR); - intl_error_set_custom_msg(NULL, "Code point out of range", 0); + intl_error_set_custom_msg(NULL, "Code point out of range"); return; } diff --git a/ext/intl/php_intl.c b/ext/intl/php_intl.c index 68fd2dedfba..28debad4133 100644 --- a/ext/intl/php_intl.c +++ b/ext/intl/php_intl.c @@ -98,10 +98,24 @@ const char *intl_locale_get_default( void ) return INTL_G(default_locale); } +static PHP_INI_MH(OnUpdateErrorLevel) +{ + zend_long *p = (zend_long *) ZEND_INI_GET_ADDR(); + *p = zend_ini_parse_quantity_warn(new_value, entry->name); + if (*p) { + php_error_docref("session.configuration", E_DEPRECATED, + "Using a value different than 0 for intl.error_level is deprecated," + " as the intl.error_level INI setting is deprecated." + " Instead the intl.use_exceptions INI setting should be enabled to throw exceptions on errors" + " or intl_get_error_code()/intl_get_error_message() should be used to manually deal with errors"); + } + return SUCCESS; +} + /* {{{ INI Settings */ PHP_INI_BEGIN() STD_PHP_INI_ENTRY(LOCALE_INI_NAME, NULL, PHP_INI_ALL, OnUpdateStringUnempty, default_locale, zend_intl_globals, intl_globals) - STD_PHP_INI_ENTRY("intl.error_level", "0", PHP_INI_ALL, OnUpdateLong, error_level, zend_intl_globals, intl_globals) + STD_PHP_INI_ENTRY("intl.error_level", "0", PHP_INI_ALL, OnUpdateErrorLevel, error_level, zend_intl_globals, intl_globals) STD_PHP_INI_BOOLEAN("intl.use_exceptions", "0", PHP_INI_ALL, OnUpdateBool, use_exceptions, zend_intl_globals, intl_globals) PHP_INI_END() /* }}} */ diff --git a/ext/intl/php_intl.stub.php b/ext/intl/php_intl.stub.php index dfb05a2b50a..d2ca22c6d29 100644 --- a/ext/intl/php_intl.stub.php +++ b/ext/intl/php_intl.stub.php @@ -173,8 +173,7 @@ class IntlException extends Exception /* calendar */ -/** @param IntlTimeZone|DateTimeZone|string|null $timezone */ -function intlcal_create_instance($timezone = null, ?string $locale = null): ?IntlCalendar {} +function intlcal_create_instance(IntlTimeZone|DateTimeZone|string|null $timezone = null, ?string $locale = null): ?IntlCalendar {} function intlcal_get_keyword_values_for_locale(string $keyword, string $locale, bool $onlyCommon): IntlIterator|false {} @@ -194,8 +193,7 @@ function intlcal_set_time(IntlCalendar $calendar, float $timestamp): bool {} function intlcal_add(IntlCalendar $calendar, int $field, int $value): bool {} -/** @param IntlTimeZone|DateTimeZone|string|null $timezone */ -function intlcal_set_time_zone(IntlCalendar $calendar, $timezone): bool {} +function intlcal_set_time_zone(IntlCalendar $calendar, IntlTimeZone|DateTimeZone|string|null $timezone): bool {} function intlcal_after(IntlCalendar $calendar, IntlCalendar $other): bool {} @@ -328,12 +326,11 @@ function intl_error_name(int $errorCode): string {} /* dateformat */ -/** @param IntlTimeZone|DateTimeZone|string|null $timezone */ function datefmt_create( ?string $locale, int $dateType = IntlDateFormatter::FULL, int $timeType = IntlDateFormatter::FULL, - $timezone = null, + IntlTimeZone|DateTimeZone|string|null $timezone = null, IntlCalendar|int|null $calendar = null, ?string $pattern = null ): ?IntlDateFormatter {} @@ -352,8 +349,7 @@ function datefmt_get_calendar_object(IntlDateFormatter $formatter): IntlCalendar function datefmt_get_timezone(IntlDateFormatter $formatter): IntlTimeZone|false {} -/** @param IntlTimeZone|DateTimeZone|string|null $timezone */ -function datefmt_set_timezone(IntlDateFormatter $formatter, $timezone): bool {} +function datefmt_set_timezone(IntlDateFormatter $formatter, IntlTimeZone|DateTimeZone|string|null $timezone): bool {} function datefmt_set_pattern(IntlDateFormatter $formatter, string $pattern): bool {} @@ -571,8 +567,7 @@ function intltz_count_equivalent_ids(string $timezoneId): int|false {} function intltz_create_default(): IntlTimeZone {} -/** @param IntlTimeZone|string|int|float|null $countryOrRawOffset */ -function intltz_create_enumeration($countryOrRawOffset = null): IntlIterator|false {} +function intltz_create_enumeration(string|int|null $countryOrRawOffset = null): IntlIterator|false {} function intltz_create_time_zone(string $timezoneId): ?IntlTimeZone {} diff --git a/ext/intl/php_intl_arginfo.h b/ext/intl/php_intl_arginfo.h index 332e5caed67..012e274296a 100644 --- a/ext/intl/php_intl_arginfo.h +++ b/ext/intl/php_intl_arginfo.h @@ -1,8 +1,8 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 0d5b028a1ab8f35e8ee1b51ce3141b6ef782af28 */ + * Stub hash: 3fa507cf4ace635ae620050db9662b3979890bc1 */ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_intlcal_create_instance, 0, 0, IntlCalendar, 1) - ZEND_ARG_INFO_WITH_DEFAULT_VALUE(0, timezone, "null") + ZEND_ARG_OBJ_TYPE_MASK(0, timezone, IntlTimeZone|DateTimeZone, MAY_BE_STRING|MAY_BE_NULL, "null") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, locale, IS_STRING, 1, "null") ZEND_END_ARG_INFO() @@ -40,7 +40,7 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_intlcal_set_time_zone, 0, 2, _IS_BOOL, 0) ZEND_ARG_OBJ_INFO(0, calendar, IntlCalendar, 0) - ZEND_ARG_INFO(0, timezone) + ZEND_ARG_OBJ_TYPE_MASK(0, timezone, IntlTimeZone|DateTimeZone, MAY_BE_STRING|MAY_BE_NULL, NULL) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_intlcal_after, 0, 2, _IS_BOOL, 0) @@ -280,7 +280,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_datefmt_create, 0, 1, IntlDateFor ZEND_ARG_TYPE_INFO(0, locale, IS_STRING, 1) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, dateType, IS_LONG, 0, "IntlDateFormatter::FULL") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, timeType, IS_LONG, 0, "IntlDateFormatter::FULL") - ZEND_ARG_INFO_WITH_DEFAULT_VALUE(0, timezone, "null") + ZEND_ARG_OBJ_TYPE_MASK(0, timezone, IntlTimeZone|DateTimeZone, MAY_BE_STRING|MAY_BE_NULL, "null") ZEND_ARG_OBJ_TYPE_MASK(0, calendar, IntlCalendar, MAY_BE_LONG|MAY_BE_NULL, "null") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, pattern, IS_STRING, 1, "null") ZEND_END_ARG_INFO() @@ -312,7 +312,7 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_datefmt_set_timezone, 0, 2, _IS_BOOL, 0) ZEND_ARG_OBJ_INFO(0, formatter, IntlDateFormatter, 0) - ZEND_ARG_INFO(0, timezone) + ZEND_ARG_OBJ_TYPE_MASK(0, timezone, IntlTimeZone|DateTimeZone, MAY_BE_STRING|MAY_BE_NULL, NULL) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_datefmt_set_pattern, 0, 2, _IS_BOOL, 0) @@ -679,7 +679,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_intltz_create_default, 0, 0, Intl ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_intltz_create_enumeration, 0, 0, IntlIterator, MAY_BE_FALSE) - ZEND_ARG_INFO_WITH_DEFAULT_VALUE(0, countryOrRawOffset, "null") + ZEND_ARG_TYPE_MASK(0, countryOrRawOffset, MAY_BE_STRING|MAY_BE_LONG|MAY_BE_NULL, "null") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_intltz_create_time_zone, 0, 1, IntlTimeZone, 1) @@ -1225,19 +1225,15 @@ static void register_php_intl_symbols(int module_number) zend_attribute *attribute_Deprecated_func_intlcal_set_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "intlcal_set", sizeof("intlcal_set") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_func_intlcal_set_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_4)); attribute_Deprecated_func_intlcal_set_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_intlcal_set_0_arg1; zend_string *attribute_Deprecated_func_intlcal_set_0_arg1_str = zend_string_init("use IntlCalendar::set(), IntlCalendar::setDate(), or IntlCalendar::setDateTime() instead", strlen("use IntlCalendar::set(), IntlCalendar::setDate(), or IntlCalendar::setDateTime() instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_intlcal_set_0_arg1, attribute_Deprecated_func_intlcal_set_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_intlcal_set_0->args[1].value, &attribute_Deprecated_func_intlcal_set_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_intlcal_set_0->args[1].value, attribute_Deprecated_func_intlcal_set_0_arg1_str); attribute_Deprecated_func_intlcal_set_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_func_intlgregcal_create_instance_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "intlgregcal_create_instance", sizeof("intlgregcal_create_instance") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_func_intlgregcal_create_instance_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_4)); attribute_Deprecated_func_intlgregcal_create_instance_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_intlgregcal_create_instance_0_arg1; zend_string *attribute_Deprecated_func_intlgregcal_create_instance_0_arg1_str = zend_string_init("use IntlGregorianCalendar::__construct(), IntlGregorianCalendar::createFromDate(), or IntlGregorianCalendar::createFromDateTime() instead", strlen("use IntlGregorianCalendar::__construct(), IntlGregorianCalendar::createFromDate(), or IntlGregorianCalendar::createFromDateTime() instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_intlgregcal_create_instance_0_arg1, attribute_Deprecated_func_intlgregcal_create_instance_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_intlgregcal_create_instance_0->args[1].value, &attribute_Deprecated_func_intlgregcal_create_instance_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_intlgregcal_create_instance_0->args[1].value, attribute_Deprecated_func_intlgregcal_create_instance_0_arg1_str); attribute_Deprecated_func_intlgregcal_create_instance_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); } diff --git a/ext/intl/resourcebundle/resourcebundle_class.c b/ext/intl/resourcebundle/resourcebundle_class.c index c64bf1d4518..165e60cc1d3 100644 --- a/ext/intl/resourcebundle/resourcebundle_class.c +++ b/ext/intl/resourcebundle/resourcebundle_class.c @@ -72,7 +72,7 @@ static zend_object *ResourceBundle_object_create( zend_class_entry *ce ) /* }}} */ /* {{{ ResourceBundle_ctor */ -static int resourcebundle_ctor(INTERNAL_FUNCTION_PARAMETERS, zend_error_handling *error_handling, bool *error_handling_replaced) +static zend_result resourcebundle_ctor(INTERNAL_FUNCTION_PARAMETERS) { char *bundlename; size_t bundlename_len = 0; @@ -92,11 +92,6 @@ static int resourcebundle_ctor(INTERNAL_FUNCTION_PARAMETERS, zend_error_handling Z_PARAM_BOOL(fallback) 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; - } - if (rb->me) { zend_throw_error(NULL, "ResourceBundle object is already constructed"); return FAILURE; @@ -119,18 +114,18 @@ static int resourcebundle_ctor(INTERNAL_FUNCTION_PARAMETERS, zend_error_handling rb->me = ures_openDirect(bundlename, locale, &INTL_DATA_ERROR_CODE(rb)); } - INTL_CTOR_CHECK_STATUS(rb, "resourcebundle_ctor: Cannot load libICU resource bundle"); + INTL_CTOR_CHECK_STATUS(rb, "Cannot load libICU resource bundle"); if (!fallback && (INTL_DATA_ERROR_CODE(rb) == U_USING_FALLBACK_WARNING || INTL_DATA_ERROR_CODE(rb) == U_USING_DEFAULT_WARNING)) { char *pbuf; intl_errors_set_code(NULL, INTL_DATA_ERROR_CODE(rb)); - spprintf(&pbuf, 0, "resourcebundle_ctor: Cannot load libICU resource " + spprintf(&pbuf, 0, "Cannot load libICU resource " "'%s' without fallback from %s to %s", bundlename ? bundlename : "(default data)", locale, ures_getLocaleByType( rb->me, ULOC_ACTUAL_LOCALE, &INTL_DATA_ERROR_CODE(rb))); - intl_errors_set_custom_msg(INTL_DATA_ERROR_P(rb), pbuf, 1); + intl_errors_set_custom_msg(INTL_DATA_ERROR_P(rb), pbuf); efree(pbuf); return FAILURE; } @@ -142,18 +137,17 @@ static int resourcebundle_ctor(INTERNAL_FUNCTION_PARAMETERS, zend_error_handling /* {{{ ResourceBundle object constructor */ PHP_METHOD( ResourceBundle, __construct ) { - zend_error_handling error_handling; - bool error_handling_replaced = 0; + const bool old_use_exception = INTL_G(use_exceptions); + const zend_long old_error_level = INTL_G(error_level); + INTL_G(use_exceptions) = true; + INTL_G(error_level) = 0; return_value = ZEND_THIS; - 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); - } - } - if (error_handling_replaced) { - zend_restore_error_handling(&error_handling); + if (resourcebundle_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU) == FAILURE) { + ZEND_ASSERT(EG(exception)); } + INTL_G(use_exceptions) = old_use_exception; + INTL_G(error_level) = old_error_level; } /* }}} */ @@ -161,7 +155,7 @@ PHP_METHOD( ResourceBundle, __construct ) PHP_FUNCTION( resourcebundle_create ) { object_init_ex( return_value, ResourceBundle_ce_ptr ); - if (resourcebundle_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, NULL, NULL) == FAILURE) { + if (resourcebundle_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU) == FAILURE) { zval_ptr_dtor(return_value); RETURN_NULL(); } @@ -214,7 +208,7 @@ static zval *resource_bundle_array_fetch( } else { spprintf( &pbuf, 0, "Cannot load resource element '%s'", key ); } - intl_errors_set_custom_msg( INTL_DATA_ERROR_P(rb), pbuf, 1 ); + intl_errors_set_custom_msg( INTL_DATA_ERROR_P(rb), pbuf); efree(pbuf); RETVAL_NULL(); return return_value; @@ -228,7 +222,7 @@ static zval *resource_bundle_array_fetch( } else { spprintf(&pbuf, 0, "Cannot load element '%s' without fallback from to %s", key, locale); } - intl_errors_set_custom_msg( INTL_DATA_ERROR_P(rb), pbuf, 1); + intl_errors_set_custom_msg( INTL_DATA_ERROR_P(rb), pbuf); efree(pbuf); RETVAL_NULL(); return return_value; @@ -307,8 +301,8 @@ static zend_result resourcebundle_array_count(zend_object *object, zend_long *co if (rb->me == NULL) { intl_errors_set(&rb->error, U_ILLEGAL_ARGUMENT_ERROR, - "Found unconstructed ResourceBundle", 0); - return 0; + "Found unconstructed ResourceBundle"); + return FAILURE; } *count = ures_getSize( rb->me ); diff --git a/ext/intl/spoofchecker/spoofchecker_class.h b/ext/intl/spoofchecker/spoofchecker_class.h index 480eeeb476f..a471c055c2c 100644 --- a/ext/intl/spoofchecker/spoofchecker_class.h +++ b/ext/intl/spoofchecker/spoofchecker_class.h @@ -73,7 +73,7 @@ extern zend_class_entry *Spoofchecker_ce_ptr; #define SPOOFCHECKER_CHECK_STATUS(co, msg) \ intl_error_set_code(NULL, SPOOFCHECKER_ERROR_CODE(co)); \ if (U_FAILURE(SPOOFCHECKER_ERROR_CODE(co))) { \ - intl_errors_set_custom_msg(SPOOFCHECKER_ERROR_P(co), msg, 0); \ + intl_errors_set_custom_msg(SPOOFCHECKER_ERROR_P(co), msg); \ RETURN_FALSE; \ } \ diff --git a/ext/intl/spoofchecker/spoofchecker_create.c b/ext/intl/spoofchecker/spoofchecker_create.c index c1cecac8412..7cb51adef4e 100644 --- a/ext/intl/spoofchecker/spoofchecker_create.c +++ b/ext/intl/spoofchecker/spoofchecker_create.c @@ -26,17 +26,17 @@ PHP_METHOD(Spoofchecker, __construct) #if U_ICU_VERSION_MAJOR_NUM < 58 int checks; #endif - zend_error_handling error_handling; SPOOFCHECKER_METHOD_INIT_VARS; ZEND_PARSE_PARAMETERS_NONE(); - zend_replace_error_handling(EH_THROW, IntlException_ce_ptr, &error_handling); - SPOOFCHECKER_METHOD_FETCH_OBJECT_NO_CHECK; co->uspoof = uspoof_open(SPOOFCHECKER_ERROR_CODE_P(co)); - INTL_METHOD_CHECK_STATUS(co, "spoofchecker: unable to open ICU Spoof Checker"); + if (U_FAILURE(INTL_DATA_ERROR_CODE(co))) { + zend_throw_exception(IntlException_ce_ptr, + "Spoofchecker::__construct(): unable to open ICU Spoof Checker", 0); + } #if U_ICU_VERSION_MAJOR_NUM >= 58 /* TODO save it into the object for further suspiction check comparison. */ @@ -56,6 +56,5 @@ PHP_METHOD(Spoofchecker, __construct) checks = uspoof_getChecks(co->uspoof, SPOOFCHECKER_ERROR_CODE_P(co)); uspoof_setChecks(co->uspoof, checks & ~USPOOF_SINGLE_SCRIPT, SPOOFCHECKER_ERROR_CODE_P(co)); #endif - zend_restore_error_handling(&error_handling); } /* }}} */ diff --git a/ext/intl/tests/breakiter___construct.phpt b/ext/intl/tests/breakiter___construct.phpt index 74d1b1beaa7..d23f4340579 100644 --- a/ext/intl/tests/breakiter___construct.phpt +++ b/ext/intl/tests/breakiter___construct.phpt @@ -4,12 +4,12 @@ IntlBreakIterator::__construct() should not be callable intl --FILE-- getMessage(), PHP_EOL; +} ?> ---EXPECTF-- -Fatal error: Uncaught Error: Call to private IntlBreakIterator::__construct() from global scope in %s:%d -Stack trace: -#0 {main} - thrown in %s on line %d +--EXPECT-- +Error: Call to private IntlBreakIterator::__construct() from global scope diff --git a/ext/intl/tests/breakiter___construct_error.phpt b/ext/intl/tests/breakiter___construct_error.phpt index 53a92009d3e..e0e35f5f4f6 100644 --- a/ext/intl/tests/breakiter___construct_error.phpt +++ b/ext/intl/tests/breakiter___construct_error.phpt @@ -5,53 +5,44 @@ intl --FILE-- getMessage() . " in " . $e->getFile() . " on line " . $e->getLine() . "\n"; -} - //missing ; at the end: try { var_dump(new IntlRuleBasedBreakIterator('[\p{Letter}\uFFFD]+;[:number:]+')); -} catch (IntlException $e) { - print_exception($e); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; } try { var_dump(new IntlRuleBasedBreakIterator()); -} catch (TypeError $e) { - print_exception($e); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; } try { var_dump(new IntlRuleBasedBreakIterator(1,2,3)); -} catch (TypeError $e) { - print_exception($e); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; } try { var_dump(new IntlRuleBasedBreakIterator('[\p{Letter}\uFFFD]+;[:number:]+;', array())); -} catch (TypeError $e) { - print_exception($e); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; } try { var_dump(new IntlRuleBasedBreakIterator('[\p{Letter}\uFFFD]+;[:number:]+;', true)); -} catch (IntlException $e) { - print_exception($e); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; } $rbbi = new IntlRuleBasedBreakIterator(".;"); try { $rbbi->__construct(".;"); -} catch (Error $e) { - print_exception($e); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; } ?> ---EXPECTF-- -Exception: IntlRuleBasedBreakIterator::__construct(): unable to create RuleBasedBreakIterator from rules (parse error on line 1, offset 31) in %s on line %d - -Exception: IntlRuleBasedBreakIterator::__construct() expects at least 1 argument, 0 given in %s on line %d - -Exception: IntlRuleBasedBreakIterator::__construct() expects at most 2 arguments, 3 given in %s on line %d - -Exception: IntlRuleBasedBreakIterator::__construct(): Argument #2 ($compiled) must be of type bool, array given in %s on line %d - -Exception: IntlRuleBasedBreakIterator::__construct(): unable to create instance from compiled rules in %s on line %d - -Exception: IntlRuleBasedBreakIterator object is already constructed in %s on line %d +--EXPECT-- +IntlException: IntlRuleBasedBreakIterator::__construct(): unable to create RuleBasedBreakIterator from rules (parse error on line 1, offset 31) +ArgumentCountError: IntlRuleBasedBreakIterator::__construct() expects at least 1 argument, 0 given +ArgumentCountError: IntlRuleBasedBreakIterator::__construct() expects at most 2 arguments, 3 given +TypeError: IntlRuleBasedBreakIterator::__construct(): Argument #2 ($compiled) must be of type bool, array given +IntlException: IntlRuleBasedBreakIterator::__construct(): unable to create instance from compiled rules +Error: IntlRuleBasedBreakIterator object is already constructed diff --git a/ext/intl/tests/breakiter_clone_basic.phpt b/ext/intl/tests/breakiter_clone_basic.phpt index ac9197c1051..7fb7837cb8c 100644 --- a/ext/intl/tests/breakiter_clone_basic.phpt +++ b/ext/intl/tests/breakiter_clone_basic.phpt @@ -4,7 +4,6 @@ IntlBreakIterator: clone handler intl --FILE-- current()); diff --git a/ext/intl/tests/breakiter_factories_basic.phpt b/ext/intl/tests/breakiter_factories_basic.phpt index 440a0e0f422..00d49e5760d 100644 --- a/ext/intl/tests/breakiter_factories_basic.phpt +++ b/ext/intl/tests/breakiter_factories_basic.phpt @@ -2,10 +2,10 @@ IntlBreakIterator factories: basic tests --EXTENSIONS-- intl +--INI-- +intl.default_locale=ja --FILE-- setText('foo bar trans'); diff --git a/ext/intl/tests/breakiter_following_basic.phpt b/ext/intl/tests/breakiter_following_basic.phpt index 0e18502c400..872e73aba3c 100644 --- a/ext/intl/tests/breakiter_following_basic.phpt +++ b/ext/intl/tests/breakiter_following_basic.phpt @@ -4,8 +4,6 @@ IntlBreakIterator::following(): basic test intl --FILE-- setText('foo bar trans zoo bee'); diff --git a/ext/intl/tests/breakiter_getLocale_basic2.phpt b/ext/intl/tests/breakiter_getLocale_basic2.phpt index ee92043187a..2ee223ac521 100644 --- a/ext/intl/tests/breakiter_getLocale_basic2.phpt +++ b/ext/intl/tests/breakiter_getLocale_basic2.phpt @@ -6,8 +6,6 @@ intl = 0) die('skip for ICU < 64.0'); ?> --FILE-- = 64.0'); ?> --FILE-- 0) die('skip for ICU <= 57.1'); ?> --FILE-- getPartsIterator(); diff --git a/ext/intl/tests/breakiter_getPartsIterator_basic2.phpt b/ext/intl/tests/breakiter_getPartsIterator_basic2.phpt index 96833990dd6..4f516c9abf7 100644 --- a/ext/intl/tests/breakiter_getPartsIterator_basic2.phpt +++ b/ext/intl/tests/breakiter_getPartsIterator_basic2.phpt @@ -8,8 +8,6 @@ if (version_compare(INTL_ICU_VERSION, '57.1') <= 0) die('skip for ICU > 57.1'); ?> --FILE-- getPartsIterator(); diff --git a/ext/intl/tests/breakiter_getPartsIterator_error.phpt b/ext/intl/tests/breakiter_getPartsIterator_error.phpt index 0b2ce3c078f..f1a5c18c825 100644 --- a/ext/intl/tests/breakiter_getPartsIterator_error.phpt +++ b/ext/intl/tests/breakiter_getPartsIterator_error.phpt @@ -4,7 +4,6 @@ IntlBreakIterator::getPartsIterator(): bad args intl --FILE-- getText()); diff --git a/ext/intl/tests/breakiter_isBoundary_basic.phpt b/ext/intl/tests/breakiter_isBoundary_basic.phpt index 238337b737d..27a1d2596e2 100644 --- a/ext/intl/tests/breakiter_isBoundary_basic.phpt +++ b/ext/intl/tests/breakiter_isBoundary_basic.phpt @@ -4,8 +4,6 @@ IntlBreakIterator::isBoundary(): basic test intl --FILE-- setText('foo bar trans zoo bee'); diff --git a/ext/intl/tests/breakiter_last_basic.phpt b/ext/intl/tests/breakiter_last_basic.phpt index d3edd504a6e..6cf579a41e9 100644 --- a/ext/intl/tests/breakiter_last_basic.phpt +++ b/ext/intl/tests/breakiter_last_basic.phpt @@ -4,7 +4,6 @@ IntlBreakIterator::last(): basic test intl --FILE-- setText('foo bar trans'); diff --git a/ext/intl/tests/breakiter_next_basic.phpt b/ext/intl/tests/breakiter_next_basic.phpt index 30d255102aa..22726bf400e 100644 --- a/ext/intl/tests/breakiter_next_basic.phpt +++ b/ext/intl/tests/breakiter_next_basic.phpt @@ -4,8 +4,6 @@ IntlBreakIterator::next(): basic test intl --FILE-- setText('foo bar trans zoo bee'); diff --git a/ext/intl/tests/breakiter_preceding_basic.phpt b/ext/intl/tests/breakiter_preceding_basic.phpt index ed238eaef20..7864f4b3c89 100644 --- a/ext/intl/tests/breakiter_preceding_basic.phpt +++ b/ext/intl/tests/breakiter_preceding_basic.phpt @@ -8,8 +8,6 @@ if (version_compare(INTL_ICU_VERSION, '57.1') > 0) die('skip for ICU <= 57.1'); ?> --FILE-- setText('foo bar trans zoo bee'); diff --git a/ext/intl/tests/breakiter_preceding_basic2.phpt b/ext/intl/tests/breakiter_preceding_basic2.phpt index 4d7ae1eb2e3..04d2e0d6546 100644 --- a/ext/intl/tests/breakiter_preceding_basic2.phpt +++ b/ext/intl/tests/breakiter_preceding_basic2.phpt @@ -8,8 +8,6 @@ if (version_compare(INTL_ICU_VERSION, '57.1') <= 0) die('skip for ICU > 57.1'); ?> --FILE-- setText('foo bar trans zoo bee'); diff --git a/ext/intl/tests/breakiter_previous_basic.phpt b/ext/intl/tests/breakiter_previous_basic.phpt index fcafe672ad9..3f297626110 100644 --- a/ext/intl/tests/breakiter_previous_basic.phpt +++ b/ext/intl/tests/breakiter_previous_basic.phpt @@ -4,8 +4,6 @@ IntlBreakIterator::previous(): basic test intl --FILE-- setText('foo bar trans'); diff --git a/ext/intl/tests/breakiter_setText_basic.phpt b/ext/intl/tests/breakiter_setText_basic.phpt index 8f15f31008d..1262e4a1e48 100644 --- a/ext/intl/tests/breakiter_setText_basic.phpt +++ b/ext/intl/tests/breakiter_setText_basic.phpt @@ -4,7 +4,6 @@ IntlBreakIterator::setText(): basic test intl --FILE-- --EXPECT-- bool(false) -string(65) "numfmt_set_symbol: invalid symbol value: U_ILLEGAL_ARGUMENT_ERROR" +string(67) "numfmt_set_symbol(): invalid symbol value: U_ILLEGAL_ARGUMENT_ERROR" bool(false) -string(65) "numfmt_set_symbol: invalid symbol value: U_ILLEGAL_ARGUMENT_ERROR" +string(67) "numfmt_set_symbol(): invalid symbol value: U_ILLEGAL_ARGUMENT_ERROR" bool(false) -string(65) "numfmt_set_symbol: invalid symbol value: U_ILLEGAL_ARGUMENT_ERROR" +string(67) "numfmt_set_symbol(): invalid symbol value: U_ILLEGAL_ARGUMENT_ERROR" bool(false) -string(65) "numfmt_set_symbol: invalid symbol value: U_ILLEGAL_ARGUMENT_ERROR" +string(67) "numfmt_set_symbol(): invalid symbol value: U_ILLEGAL_ARGUMENT_ERROR" diff --git a/ext/intl/tests/bug58756_MessageFormatter_variant2.phpt b/ext/intl/tests/bug58756_MessageFormatter_variant2.phpt index 6bfbbd8a2f0..c06ba8dd277 100644 --- a/ext/intl/tests/bug58756_MessageFormatter_variant2.phpt +++ b/ext/intl/tests/bug58756_MessageFormatter_variant2.phpt @@ -2,6 +2,8 @@ Bug #58756: w.r.t MessageFormatter --EXTENSIONS-- intl +--INI-- +date.timezone=America/New_York --SKIPIF-- --FILE-- compare('h', 'H'); +try { + $a = $c->compare('h', 'H'); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; +} ?> ---EXPECTF-- -Fatal error: Uncaught Error: Object not initialized in %s:%d -Stack trace: -#0 %s(%d): Collator->compare('h', 'H') -#1 {main} - thrown in %s on line %d +--EXPECT-- +Error: Object not initialized diff --git a/ext/intl/tests/bug60192-getlocale.phpt b/ext/intl/tests/bug60192-getlocale.phpt index fed0d634cc8..4d648b3ec71 100644 --- a/ext/intl/tests/bug60192-getlocale.phpt +++ b/ext/intl/tests/bug60192-getlocale.phpt @@ -12,11 +12,11 @@ class Collator2 extends Collator{ } $c = new Collator2(); -$c->getLocale(Locale::ACTUAL_LOCALE); +try { + $c->getLocale(Locale::ACTUAL_LOCALE); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; +} ?> ---EXPECTF-- -Fatal error: Uncaught Error: Object not initialized in %s:%d -Stack trace: -#0 %s(%d): Collator->getLocale(0) -#1 {main} - thrown in %s on line %d +--EXPECT-- +Error: Object not initialized diff --git a/ext/intl/tests/bug60192-getsortkey.phpt b/ext/intl/tests/bug60192-getsortkey.phpt index aeadf8db75a..39a1c766e7f 100644 --- a/ext/intl/tests/bug60192-getsortkey.phpt +++ b/ext/intl/tests/bug60192-getsortkey.phpt @@ -12,11 +12,11 @@ class Collator2 extends Collator{ } $c = new Collator2(); -$c->getSortKey('h'); +try { + $c->getSortKey('h'); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; +} ?> ---EXPECTF-- -Fatal error: Uncaught Error: Object not initialized in %s:%d -Stack trace: -#0 %s(%d): Collator->getSortKey('h') -#1 {main} - thrown in %s on line %d +--EXPECT-- +Error: Object not initialized diff --git a/ext/intl/tests/bug60192-sort.phpt b/ext/intl/tests/bug60192-sort.phpt index 1166df81618..e95fd6237cf 100644 --- a/ext/intl/tests/bug60192-sort.phpt +++ b/ext/intl/tests/bug60192-sort.phpt @@ -13,11 +13,11 @@ class Collator2 extends Collator{ $c = new Collator2(); $a = array('a', 'b'); -$c->sort($a); +try { + $c->sort($a); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; +} ?> ---EXPECTF-- -Fatal error: Uncaught Error: Object not initialized in %s:%d -Stack trace: -#0 %s(%d): Collator->sort(Array) -#1 {main} - thrown in %s on line %d +--EXPECT-- +Error: Object not initialized diff --git a/ext/intl/tests/bug60192-sortwithsortkeys.phpt b/ext/intl/tests/bug60192-sortwithsortkeys.phpt index 46aacb052ba..532d153fb5b 100644 --- a/ext/intl/tests/bug60192-sortwithsortkeys.phpt +++ b/ext/intl/tests/bug60192-sortwithsortkeys.phpt @@ -13,11 +13,11 @@ class Collator2 extends Collator{ $c = new Collator2(); $a = array('a', 'b'); -$c->sortWithSortKeys($a); +try { + $c->sortWithSortKeys($a); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; +} ?> ---EXPECTF-- -Fatal error: Uncaught Error: Object not initialized in %s:%d -Stack trace: -#0 %s(%d): Collator->sortWithSortKeys(Array) -#1 {main} - thrown in %s on line %d +--EXPECT-- +Error: Object not initialized diff --git a/ext/intl/tests/bug62017.phpt b/ext/intl/tests/bug62017.phpt index 53b0deb4fa7..c149b120246 100644 --- a/ext/intl/tests/bug62017.phpt +++ b/ext/intl/tests/bug62017.phpt @@ -4,23 +4,20 @@ Bug #62017: datefmt_create with incorrectly encoded timezone leaks pattern intl --FILE-- getMessage() . " in " . $e->getFile() . " on line " . $e->getLine() . PHP_EOL; +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; } try { - new IntlDateFormatter('', IntlDateFormatter::NONE, IntlDateFormatter::NONE, "Europe/Lisbon", + new IntlDateFormatter('', IntlDateFormatter::NONE, IntlDateFormatter::NONE, "Europe/Lisbon", IntlDateFormatter::GREGORIAN, "\x80"); -} catch (IntlException $e) { - echo PHP_EOL."Exception: " . $e->getMessage() . " in " . $e->getFile() . " on line " . $e->getLine() . PHP_EOL; +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; } ?> ---EXPECTF-- - -Exception: datefmt_create: Time zone identifier given is not a valid UTF-8 string in %s on line %d - -Exception: IntlDateFormatter::__construct(): datefmt_create: error converting pattern to UTF-16 in %s on line %d +--EXPECT-- +IntlException: datefmt_create(): Time zone identifier given is not a valid UTF-8 string +IntlException: IntlDateFormatter::__construct(): error converting pattern to UTF-16 diff --git a/ext/intl/tests/bug62081.phpt b/ext/intl/tests/bug62081.phpt index d1c066994b6..5b6f1d50c9b 100644 --- a/ext/intl/tests/bug62081.phpt +++ b/ext/intl/tests/bug62081.phpt @@ -6,13 +6,12 @@ date.timezone=Atlantic/Azores intl --FILE-- __construct('en', 1, 1)); +try { + var_dump($x->__construct('en', 1, 1)); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; +} ?> ---EXPECTF-- -Fatal error: Uncaught IntlException: IntlDateFormatter::__construct(): datefmt_create: cannot call constructor twice in %sbug62081.php:4 -Stack trace: -#0 %sbug62081.php(4): IntlDateFormatter->__construct('en', 1, 1) -#1 {main} - thrown in %sbug62081.php on line 4 +--EXPECT-- +IntlException: IntlDateFormatter::__construct(): cannot call constructor twice diff --git a/ext/intl/tests/bug67397.phpt b/ext/intl/tests/bug67397.phpt index 7786c81dd4d..023f47725ab 100644 --- a/ext/intl/tests/bug67397.phpt +++ b/ext/intl/tests/bug67397.phpt @@ -5,17 +5,17 @@ intl --FILE-- --EXPECT-- -false -'locale_get_display_name : name too long: U_ILLEGAL_ARGUMENT_ERROR' +bool(false) +string(65) "Locale::getDisplayName(): name too long: U_ILLEGAL_ARGUMENT_ERROR" +bool(false) +string(66) "locale_get_display_name(): name too long: U_ILLEGAL_ARGUMENT_ERROR" diff --git a/ext/intl/tests/bug72533.phpt b/ext/intl/tests/bug72533.phpt index c7cc90f9c3b..e294f98213e 100644 --- a/ext/intl/tests/bug72533.phpt +++ b/ext/intl/tests/bug72533.phpt @@ -5,26 +5,30 @@ intl --FILE-- --EXPECT-- -false -'locale_accept_from_http: locale string too long: U_ILLEGAL_ARGUMENT_ERROR' -'en' +bool(false) +string(74) "Locale::acceptFromHttp(): locale string too long: U_ILLEGAL_ARGUMENT_ERROR" +bool(false) +string(75) "locale_accept_from_http(): locale string too long: U_ILLEGAL_ARGUMENT_ERROR" +bool(false) +string(74) "Locale::acceptFromHttp(): locale string too long: U_ILLEGAL_ARGUMENT_ERROR" +bool(false) +string(75) "locale_accept_from_http(): locale string too long: U_ILLEGAL_ARGUMENT_ERROR" diff --git a/ext/intl/tests/bug75317.phpt b/ext/intl/tests/bug75317.phpt index 1dd96950bb0..4df45f37bf8 100644 --- a/ext/intl/tests/bug75317.phpt +++ b/ext/intl/tests/bug75317.phpt @@ -1,5 +1,5 @@ --TEST-- -Bug #75317 (UConverter::setDestinationEncoding changes source instead of destinatination) +Bug #75317 (UConverter::setDestinationEncoding changes source instead of destination) --EXTENSIONS-- intl --FILE-- diff --git a/ext/intl/tests/calendar_add_basic.phpt b/ext/intl/tests/calendar_add_basic.phpt index f732f02f358..9a7a16f844f 100644 --- a/ext/intl/tests/calendar_add_basic.phpt +++ b/ext/intl/tests/calendar_add_basic.phpt @@ -2,12 +2,11 @@ IntlCalendar::add() basic test --INI-- date.timezone=Atlantic/Azores +intl.default_locale=nl --EXTENSIONS-- intl --FILE-- --EXPECT-- float(1330578367000) -float(1330578367000) \ No newline at end of file +float(1330578367000) diff --git a/ext/intl/tests/calendar_add_error.phpt b/ext/intl/tests/calendar_add_error.phpt deleted file mode 100644 index a56576df459..00000000000 --- a/ext/intl/tests/calendar_add_error.phpt +++ /dev/null @@ -1,18 +0,0 @@ ---TEST-- -IntlCalendar::add(): bad arguments ---INI-- -date.timezone=Atlantic/Azores ---EXTENSIONS-- -intl ---FILE-- - ---EXPECTF-- -Fatal error: Uncaught TypeError: intlcal_add(): Argument #1 ($calendar) must be of type IntlCalendar, int given in %s:%d -Stack trace: -#0 %s(%d): intlcal_add(1, 2, 3) -#1 {main} - thrown in %s on line %d diff --git a/ext/intl/tests/calendar_before_after_error.phpt b/ext/intl/tests/calendar_before_after_error.phpt deleted file mode 100644 index 8688059124c..00000000000 --- a/ext/intl/tests/calendar_before_after_error.phpt +++ /dev/null @@ -1,77 +0,0 @@ ---TEST-- -IntlCalendar::before()/after(): bad arguments ---INI-- -date.timezone=Atlantic/Azores ---EXTENSIONS-- -intl ---FILE-- -after()); -} catch (Error $ex) { - echo "error: " . $ex->getCode() . ", " . $ex->getMessage() . "\n\n"; -} -try { - var_dump($c->before()); -} catch (Error $ex) { - echo "error: " . $ex->getCode() . ", " . $ex->getMessage() . "\n\n"; -} - -try { - var_dump($c->after(1)); -} catch (Error $ex) { - echo "error: " . $ex->getCode() . ", " . $ex->getMessage() . "\n\n"; -} -try { - var_dump($c->before(1)); -} catch (Error $ex) { - echo "error: " . $ex->getCode() . ", " . $ex->getMessage() . "\n\n"; -} - -try{ - var_dump($c->after($c, 1)); -} catch (Error $ex) { - echo "error: " . $ex->getCode() . ", " . $ex->getMessage() . "\n\n"; -} -try { - var_dump($c->before($c, 1)); -} catch (Error $ex) { - echo "error: " . $ex->getCode() . ", " . $ex->getMessage() . "\n\n"; -} - -try { - var_dump(intlcal_after($c)); -} catch (Error $ex) { - echo "error: " . $ex->getCode() . ", " . $ex->getMessage() . "\n\n"; -} -try { - var_dump(intlcal_before($c)); -} catch (Error $ex) { - echo "error: " . $ex->getCode() . ", " . $ex->getMessage() . "\n\n"; -} -?> ---EXPECT-- -error: 0, IntlCalendar::after() expects exactly 1 argument, 0 given - -error: 0, IntlCalendar::before() expects exactly 1 argument, 0 given - -error: 0, IntlCalendar::after(): Argument #1 ($other) must be of type IntlCalendar, int given - -error: 0, IntlCalendar::before(): Argument #1 ($other) must be of type IntlCalendar, int given - -error: 0, IntlCalendar::after() expects exactly 1 argument, 2 given - -error: 0, IntlCalendar::before() expects exactly 1 argument, 2 given - -error: 0, intlcal_after() expects exactly 2 arguments, 1 given - -error: 0, intlcal_before() expects exactly 2 arguments, 1 given diff --git a/ext/intl/tests/calendar_clear_basic.phpt b/ext/intl/tests/calendar_clear_basic.phpt index df3ecc97589..f9edbac9c03 100644 --- a/ext/intl/tests/calendar_clear_basic.phpt +++ b/ext/intl/tests/calendar_clear_basic.phpt @@ -2,10 +2,10 @@ IntlCalendar::clear() basic test --EXTENSIONS-- intl +--INI-- +intl.default_locale=nl --FILE-- clear()); @@ -33,4 +33,4 @@ int(0) int(0) int(0) int(0) -float(-3600000) \ No newline at end of file +float(-3600000) diff --git a/ext/intl/tests/calendar_clear_error.phpt b/ext/intl/tests/calendar_clear_error.phpt index 7880275a7c1..8f1695564e9 100644 --- a/ext/intl/tests/calendar_clear_error.phpt +++ b/ext/intl/tests/calendar_clear_error.phpt @@ -1,7 +1,5 @@ --TEST-- IntlCalendar::clear(): bad arguments ---INI-- -date.timezone=Atlantic/Azores --EXTENSIONS-- intl --FILE-- @@ -20,13 +18,7 @@ try { echo $e->getMessage() . \PHP_EOL; } -try { - var_dump(intlcal_clear(1, 2)); -} catch (\TypeError $e) { - echo $e->getMessage() . \PHP_EOL; -} ?> --EXPECT-- IntlCalendar::clear(): Argument #1 ($field) must be a valid field intlcal_clear(): Argument #2 ($field) must be a valid field -intlcal_clear(): Argument #1 ($calendar) must be of type IntlCalendar, int given diff --git a/ext/intl/tests/calendar_clear_variation1.phpt b/ext/intl/tests/calendar_clear_variation1.phpt index 75f026d0521..a485747f4d2 100644 --- a/ext/intl/tests/calendar_clear_variation1.phpt +++ b/ext/intl/tests/calendar_clear_variation1.phpt @@ -1,7 +1,7 @@ --TEST-- IntlCalendar::clear() 1 arg variation --INI-- -date.timezone=Atlantic/Azores +intl.default_locale=nl --EXTENSIONS-- intl --SKIPIF-- @@ -12,16 +12,14 @@ if (version_compare(INTL_ICU_VERSION, '73.1') >= 0 && version_compare(INTL_ICU_V ?> --FILE-- setTime(strtotime('2012-02-29 05:06:07 +0000') * 1000); -//print_R($intlcal); + var_dump($intlcal->isSet(IntlCalendar::FIELD_MONTH)); var_dump($intlcal->clear(IntlCalendar::FIELD_MONTH)); var_dump($intlcal->isSet(IntlCalendar::FIELD_MONTH)); -//print_R($intlcal); + var_dump( $intlcal->getTime(), strtotime('2012-01-29 05:06:07 +0000') * 1000. diff --git a/ext/intl/tests/calendar_createInstance_basic.phpt b/ext/intl/tests/calendar_createInstance_basic.phpt index c2ddd976094..f19f7c05358 100644 --- a/ext/intl/tests/calendar_createInstance_basic.phpt +++ b/ext/intl/tests/calendar_createInstance_basic.phpt @@ -2,12 +2,11 @@ IntlCalendar::createInstance() basic test --EXTENSIONS-- intl +--INI-- +intl.default_locale=nl +date.timezone=Europe/Amsterdam --FILE-- getTimeZone()); diff --git a/ext/intl/tests/calendar_createInstance_error.phpt b/ext/intl/tests/calendar_createInstance_error.phpt index a48b6b12c2d..28ade19b8fc 100644 --- a/ext/intl/tests/calendar_createInstance_error.phpt +++ b/ext/intl/tests/calendar_createInstance_error.phpt @@ -4,7 +4,6 @@ IntlCalendar::createInstance: bad arguments intl --FILE-- --EXPECT-- -intlcal_create_instance: passed IntlTimeZone is not properly constructed +intlcal_create_instance(): passed IntlTimeZone is not properly constructed diff --git a/ext/intl/tests/calendar_createInstance_variation1.phpt b/ext/intl/tests/calendar_createInstance_variation1.phpt index a963e9ef759..4c0848d80f1 100644 --- a/ext/intl/tests/calendar_createInstance_variation1.phpt +++ b/ext/intl/tests/calendar_createInstance_variation1.phpt @@ -2,12 +2,11 @@ IntlCalendar::createInstance() argument variations --EXTENSIONS-- intl +--INI-- +date.timezone=Europe/Amsterdam +intl.default_locale=nl --FILE-- getTimeZone()); diff --git a/ext/intl/tests/calendar_equals_before_after_basic.phpt b/ext/intl/tests/calendar_equals_before_after_basic.phpt index 36999bcb4eb..4a7db1a708f 100644 --- a/ext/intl/tests/calendar_equals_before_after_basic.phpt +++ b/ext/intl/tests/calendar_equals_before_after_basic.phpt @@ -2,12 +2,11 @@ IntlCalendar::equals(), ::before() and ::after() basic test --INI-- date.timezone=Atlantic/Azores +intl.default_locale=nl --EXTENSIONS-- intl --FILE-- equals()); -} catch (Error $ex) { - echo "error: " . $ex->getCode() . ", " . $ex->getMessage() . "\n\n"; -} -try { - var_dump($c->equals(new stdclass)); -} catch (Error $ex) { - echo "error: " . $ex->getCode() . ", " . $ex->getMessage() . "\n\n"; -} -try { - var_dump($c->equals(1, 2)); -} catch (Error $ex) { - echo "error: " . $ex->getCode() . ", " . $ex->getMessage() . "\n\n"; -} - - -try { - var_dump(intlcal_equals($c, array())); -} catch (Error $ex) { - echo "error: " . $ex->getCode() . ", " . $ex->getMessage() . "\n\n"; -} -try { - var_dump(intlcal_equals(1, $c)); -} catch (Error $ex) { - echo "error: " . $ex->getCode() . ", " . $ex->getMessage() . "\n\n"; -} -?> ---EXPECT-- -error: 0, IntlCalendar::equals() expects exactly 1 argument, 0 given - -error: 0, IntlCalendar::equals(): Argument #1 ($other) must be of type IntlCalendar, stdClass given - -error: 0, IntlCalendar::equals() expects exactly 1 argument, 2 given - -error: 0, intlcal_equals(): Argument #2 ($other) must be of type IntlCalendar, array given - -error: 0, intlcal_equals(): Argument #1 ($calendar) must be of type IntlCalendar, int given diff --git a/ext/intl/tests/calendar_fieldDifference_basic.phpt b/ext/intl/tests/calendar_fieldDifference_basic.phpt index 4c910092a72..cb13fba7072 100644 --- a/ext/intl/tests/calendar_fieldDifference_basic.phpt +++ b/ext/intl/tests/calendar_fieldDifference_basic.phpt @@ -2,12 +2,11 @@ IntlCalendar::fieldDifference() basic test --INI-- date.timezone=Atlantic/Azores +intl.default_locale=nl --EXTENSIONS-- intl --FILE-- setTime(strtotime('2012-02-29 05:06:07 +0000') * 1000); @@ -28,4 +27,4 @@ var_dump( --EXPECT-- int(3601) int(6) -int(61) \ No newline at end of file +int(61) diff --git a/ext/intl/tests/calendar_fieldDifference_error.phpt b/ext/intl/tests/calendar_fieldDifference_error.phpt index f538a0db662..31070a39529 100644 --- a/ext/intl/tests/calendar_fieldDifference_error.phpt +++ b/ext/intl/tests/calendar_fieldDifference_error.phpt @@ -1,38 +1,16 @@ --TEST-- IntlCalendar::fieldDifference(): bad arguments ---INI-- -date.timezone=Atlantic/Azores --EXTENSIONS-- intl --FILE-- fieldDifference($c, 2, 3)); -} catch (TypeError $e) { - echo $e->getMessage(), "\n"; -} var_dump($c->fieldDifference(INF, 2)); +var_dump($c->getErrorMessage()); -try { - var_dump(intlcal_field_difference($c, 0, 1, 2)); -} catch (TypeError $e) { - echo $e->getMessage(), "\n"; -} -var_dump(intlcal_field_difference(1, 0, 1)); ?> ---EXPECTF-- -IntlCalendar::fieldDifference() expects exactly 2 arguments, 3 given - -Warning: IntlCalendar::fieldDifference(): intlcal_field_difference: Call to ICU method has failed in %s on line %d +--EXPECT-- bool(false) -intlcal_field_difference() expects exactly 3 arguments, 4 given - -Fatal error: Uncaught TypeError: intlcal_field_difference(): Argument #1 ($calendar) must be of type IntlCalendar, int given in %s:%d -Stack trace: -#0 %s(%d): intlcal_field_difference(1, 0, 1) -#1 {main} - thrown in %s on line %d +string(88) "IntlCalendar::fieldDifference(): Call to ICU method has failed: U_ILLEGAL_ARGUMENT_ERROR" diff --git a/ext/intl/tests/calendar_fromDateTime_basic.phpt b/ext/intl/tests/calendar_fromDateTime_basic.phpt index ba68b267563..d91a0e80bc6 100644 --- a/ext/intl/tests/calendar_fromDateTime_basic.phpt +++ b/ext/intl/tests/calendar_fromDateTime_basic.phpt @@ -2,11 +2,11 @@ IntlCalendar::fromDateTime(): basic test --EXTENSIONS-- intl +--INI-- +intl.default_locale=nl_NL +date.timezone=Europe/Lisbon --FILE-- getMessage(), PHP_EOL; } + class A extends DateTime { -function __construct() {} + function __construct() {} } var_dump(IntlCalendar::fromDateTime(new A)); +var_dump(intl_get_error_message()); $date = new DateTime('2012-01-01 00:00:00 +24:00'); var_dump(IntlCalendar::fromDateTime($date)); +var_dump(intl_get_error_message()); $date = new DateTime('2012-01-01 00:00:00 WEST'); var_dump(IntlCalendar::fromDateTime($date)); +var_dump(intl_get_error_message()); + ?> ---EXPECTF-- -threw exception, OK -Warning: IntlCalendar::fromDateTime(): intlcal_from_date_time: DateTime object is unconstructed in %s on line %d +--EXPECT-- +DateMalformedStringException: Failed to parse time string (foobar) at position 0 (f): The timezone could not be found in the database NULL - -Warning: IntlCalendar::fromDateTime(): intlcal_from_date_time: object has an time zone offset that's too large in %s on line %d +string(88) "IntlCalendar::fromDateTime(): DateTime object is unconstructed: U_ILLEGAL_ARGUMENT_ERROR" NULL - -Warning: IntlCalendar::fromDateTime(): intlcal_from_date_time: time zone id 'WEST' extracted from ext/date DateTimeZone not recognized in %s on line %d +string(103) "IntlCalendar::fromDateTime(): object has an time zone offset that's too large: U_ILLEGAL_ARGUMENT_ERROR" NULL +string(127) "IntlCalendar::fromDateTime(): time zone id 'WEST' extracted from ext/date DateTimeZone not recognized: U_ILLEGAL_ARGUMENT_ERROR" diff --git a/ext/intl/tests/calendar_getAvailableLocales_basic.phpt b/ext/intl/tests/calendar_getAvailableLocales_basic.phpt index 38824b0924a..85e5ed9acf9 100644 --- a/ext/intl/tests/calendar_getAvailableLocales_basic.phpt +++ b/ext/intl/tests/calendar_getAvailableLocales_basic.phpt @@ -2,10 +2,10 @@ IntlCalendar::getAvailableLocales() basic test --EXTENSIONS-- intl +--INI-- +intl.default_locale=nl --FILE-- 100); @@ -16,4 +16,4 @@ var_dump(in_array('pt', $locales)); ?> --EXPECT-- bool(true) -bool(true) \ No newline at end of file +bool(true) diff --git a/ext/intl/tests/calendar_getDayOfWeekType_basic2.phpt b/ext/intl/tests/calendar_getDayOfWeekType_basic2.phpt index 1694d87c59b..7097b495da6 100644 --- a/ext/intl/tests/calendar_getDayOfWeekType_basic2.phpt +++ b/ext/intl/tests/calendar_getDayOfWeekType_basic2.phpt @@ -1,13 +1,9 @@ --TEST-- IntlCalendar::getDayOfWeekType() basic test ---INI-- -date.timezone=Atlantic/Azores --EXTENSIONS-- intl --FILE-- setTime(strtotime('2012-02-29 00:00:00 +0000') * 1000); diff --git a/ext/intl/tests/calendar_getDayOfWeekType_error.phpt b/ext/intl/tests/calendar_getDayOfWeekType_error.phpt index e239f830f17..fdea44c17fa 100644 --- a/ext/intl/tests/calendar_getDayOfWeekType_error.phpt +++ b/ext/intl/tests/calendar_getDayOfWeekType_error.phpt @@ -1,7 +1,5 @@ --TEST-- IntlCalendar::getDayOfWeekOfType(): bad arguments ---INI-- -date.timezone=Atlantic/Azores --EXTENSIONS-- intl --FILE-- @@ -14,12 +12,6 @@ try { echo $e->getMessage() . \PHP_EOL; } -try { - var_dump(intlcal_get_day_of_week_type(1, 1)); -} catch (\TypeError $e) { - echo $e->getMessage() . \PHP_EOL; -} ?> --EXPECT-- IntlCalendar::getDayOfWeekType(): Argument #1 ($dayOfWeek) must be a valid day of the week -intlcal_get_day_of_week_type(): Argument #1 ($calendar) must be of type IntlCalendar, int given diff --git a/ext/intl/tests/calendar_getErrorCode_error.phpt b/ext/intl/tests/calendar_getErrorCode_error.phpt deleted file mode 100644 index cd4c644f1fa..00000000000 --- a/ext/intl/tests/calendar_getErrorCode_error.phpt +++ /dev/null @@ -1,18 +0,0 @@ ---TEST-- -IntlCalendar::getErrorCode(): bad arguments ---INI-- -date.timezone=Atlantic/Azores ---EXTENSIONS-- -intl ---FILE-- - ---EXPECTF-- -Fatal error: Uncaught TypeError: intlcal_get_error_code(): Argument #1 ($calendar) must be of type IntlCalendar, null given in %s:%d -Stack trace: -#0 %s(%d): intlcal_get_error_code(NULL) -#1 {main} - thrown in %s on line %d diff --git a/ext/intl/tests/calendar_getErrorCode_getErrorMessage_basic.phpt b/ext/intl/tests/calendar_getErrorCode_getErrorMessage_basic.phpt index 689ec4b16a2..e1431f5815d 100644 --- a/ext/intl/tests/calendar_getErrorCode_getErrorMessage_basic.phpt +++ b/ext/intl/tests/calendar_getErrorCode_getErrorMessage_basic.phpt @@ -2,38 +2,35 @@ IntlCalendar::getErrorCode(), ::getErrorMessage() basic test --INI-- date.timezone=Atlantic/Azores +intl.default_locale=nl --EXTENSIONS-- intl --FILE-- getErrorCode(), - intlcal_get_error_code($intlcal), - $intlcal->getErrorMessage(), - intlcal_get_error_message($intlcal) + $intlcal->getErrorCode(), + intlcal_get_error_code($intlcal), + $intlcal->getErrorMessage(), + intlcal_get_error_message($intlcal) ); $intlcal->add(IntlCalendar::FIELD_SECOND, 2147483647); $intlcal->fieldDifference(-PHP_INT_MAX, IntlCalendar::FIELD_SECOND); var_dump( - $intlcal->getErrorCode(), - intlcal_get_error_code($intlcal), - $intlcal->getErrorMessage(), - intlcal_get_error_message($intlcal) + $intlcal->getErrorCode(), + intlcal_get_error_code($intlcal), + $intlcal->getErrorMessage(), + intlcal_get_error_message($intlcal) ); ?> ---EXPECTF-- +--EXPECT-- int(0) int(0) string(12) "U_ZERO_ERROR" string(12) "U_ZERO_ERROR" - -Warning: IntlCalendar::fieldDifference(): intlcal_field_difference: Call to ICU method has failed in %s on line %d int(1) int(1) -string(81) "intlcal_field_difference: Call to ICU method has failed: U_ILLEGAL_ARGUMENT_ERROR" -string(81) "intlcal_field_difference: Call to ICU method has failed: U_ILLEGAL_ARGUMENT_ERROR" +string(88) "IntlCalendar::fieldDifference(): Call to ICU method has failed: U_ILLEGAL_ARGUMENT_ERROR" +string(88) "IntlCalendar::fieldDifference(): Call to ICU method has failed: U_ILLEGAL_ARGUMENT_ERROR" diff --git a/ext/intl/tests/calendar_getErrorMessage_error.phpt b/ext/intl/tests/calendar_getErrorMessage_error.phpt deleted file mode 100644 index c6713290bea..00000000000 --- a/ext/intl/tests/calendar_getErrorMessage_error.phpt +++ /dev/null @@ -1,18 +0,0 @@ ---TEST-- -IntlCalendar::getErrorMessage(): bad arguments ---INI-- -date.timezone=Atlantic/Azores ---EXTENSIONS-- -intl ---FILE-- - ---EXPECTF-- -Fatal error: Uncaught TypeError: intlcal_get_error_message(): Argument #1 ($calendar) must be of type IntlCalendar, null given in %s:%d -Stack trace: -#0 %s(%d): intlcal_get_error_message(NULL) -#1 {main} - thrown in %s on line %d diff --git a/ext/intl/tests/calendar_getFirstDayOfWeek_basic.phpt b/ext/intl/tests/calendar_getFirstDayOfWeek_basic.phpt index 0cf0b885278..ae91595afba 100644 --- a/ext/intl/tests/calendar_getFirstDayOfWeek_basic.phpt +++ b/ext/intl/tests/calendar_getFirstDayOfWeek_basic.phpt @@ -2,10 +2,10 @@ IntlCalendar::getFirstDayOfWeek() basic test --EXTENSIONS-- intl +--INI-- +intl.default_locale=nl --FILE-- getFirstDayOfWeek()); @@ -13,4 +13,4 @@ var_dump(intlcal_get_first_day_of_week($intlcal)); ?> --EXPECT-- int(2) -int(2) \ No newline at end of file +int(2) diff --git a/ext/intl/tests/calendar_getFirstDayOfWeek_error.phpt b/ext/intl/tests/calendar_getFirstDayOfWeek_error.phpt deleted file mode 100644 index fb129437a7c..00000000000 --- a/ext/intl/tests/calendar_getFirstDayOfWeek_error.phpt +++ /dev/null @@ -1,18 +0,0 @@ ---TEST-- -IntlCalendar::getFirstDayOfWeek(): bad arguments ---INI-- -date.timezone=Atlantic/Azores ---EXTENSIONS-- -intl ---FILE-- - ---EXPECTF-- -Fatal error: Uncaught TypeError: intlcal_get_first_day_of_week(): Argument #1 ($calendar) must be of type IntlCalendar, int given in %s:%d -Stack trace: -#0 %s(%d): intlcal_get_first_day_of_week(1) -#1 {main} - thrown in %s on line %d diff --git a/ext/intl/tests/calendar_getKeywordValuesForLocale_basic.phpt b/ext/intl/tests/calendar_getKeywordValuesForLocale_basic.phpt index e6c05aa4273..eea0a325b96 100644 --- a/ext/intl/tests/calendar_getKeywordValuesForLocale_basic.phpt +++ b/ext/intl/tests/calendar_getKeywordValuesForLocale_basic.phpt @@ -4,27 +4,20 @@ IntlCalendar::getKeywordValuesForLocale() basic test intl --FILE-- 8); var_dump(in_array('japanese', $var)); ?> --EXPECT-- -Array -( - [0] => gregorian -) +array(1) { + [0]=> + string(9) "gregorian" +} bool(true) bool(true) diff --git a/ext/intl/tests/calendar_getLocale_basic.phpt b/ext/intl/tests/calendar_getLocale_basic.phpt index 92311ad4191..9c3eece1c5f 100644 --- a/ext/intl/tests/calendar_getLocale_basic.phpt +++ b/ext/intl/tests/calendar_getLocale_basic.phpt @@ -2,10 +2,10 @@ IntlCalendar::getLocale() basic test --EXTENSIONS-- intl +--INI-- +intl.default_locale=nl --FILE-- getLocale(Locale::ACTUAL_LOCALE)); diff --git a/ext/intl/tests/calendar_getLocale_error.phpt b/ext/intl/tests/calendar_getLocale_error.phpt deleted file mode 100644 index 7b51734fe27..00000000000 --- a/ext/intl/tests/calendar_getLocale_error.phpt +++ /dev/null @@ -1,18 +0,0 @@ ---TEST-- -IntlCalendar::getLocale(): bad arguments ---INI-- -date.timezone=Atlantic/Azores ---EXTENSIONS-- -intl ---FILE-- - ---EXPECTF-- -Fatal error: Uncaught ArgumentCountError: intlcal_get_locale() expects exactly 2 arguments, 1 given in %s:%d -Stack trace: -#0 %s(%d): intlcal_get_locale(1) -#1 {main} - thrown in %s on line %d diff --git a/ext/intl/tests/calendar_getMinimalDaysInFirstWeek_basic.phpt b/ext/intl/tests/calendar_getMinimalDaysInFirstWeek_basic.phpt index 42f7a56b440..fe34cd04899 100644 --- a/ext/intl/tests/calendar_getMinimalDaysInFirstWeek_basic.phpt +++ b/ext/intl/tests/calendar_getMinimalDaysInFirstWeek_basic.phpt @@ -2,10 +2,10 @@ IntlCalendar::getMinimalDaysInFirstWeek() basic test --EXTENSIONS-- intl +--INI-- +intl.default_locale=nl --FILE-- getMinimalDaysInFirstWeek()); diff --git a/ext/intl/tests/calendar_getMinimalDaysInFirstWeek_error.phpt b/ext/intl/tests/calendar_getMinimalDaysInFirstWeek_error.phpt deleted file mode 100644 index 53ff687ee8c..00000000000 --- a/ext/intl/tests/calendar_getMinimalDaysInFirstWeek_error.phpt +++ /dev/null @@ -1,18 +0,0 @@ ---TEST-- -IntlCalendar::getMinimalDaysInFirstWeek(): bad arguments ---INI-- -date.timezone=Atlantic/Azores ---EXTENSIONS-- -intl ---FILE-- - ---EXPECTF-- -Fatal error: Uncaught TypeError: intlcal_get_minimal_days_in_first_week(): Argument #1 ($calendar) must be of type IntlCalendar, int given in %s:%d -Stack trace: -#0 %s(%d): intlcal_get_minimal_days_in_first_week(1) -#1 {main} - thrown in %s on line %d diff --git a/ext/intl/tests/calendar_getNow_basic.phpt b/ext/intl/tests/calendar_getNow_basic.phpt index ddc21208b0c..2b5eb896342 100644 --- a/ext/intl/tests/calendar_getNow_basic.phpt +++ b/ext/intl/tests/calendar_getNow_basic.phpt @@ -4,8 +4,6 @@ IntlCalendar::getNow() basic test intl --FILE-- ---EXPECTF-- -Fatal error: Uncaught TypeError: intlcal_get_skipped_wall_time_option(): Argument #1 ($calendar) must be of type IntlCalendar, int given in %s:%d -Stack trace: -#0 %s(%d): intlcal_get_skipped_wall_time_option(1) -#1 {main} - thrown in %s on line %d diff --git a/ext/intl/tests/calendar_getTimeZone_basic.phpt b/ext/intl/tests/calendar_getTimeZone_basic.phpt index 7d19f19be7c..4b98c1d648d 100644 --- a/ext/intl/tests/calendar_getTimeZone_basic.phpt +++ b/ext/intl/tests/calendar_getTimeZone_basic.phpt @@ -4,8 +4,6 @@ IntlCalendar::getTimeZone() basic test intl --FILE-- getTimeZone()); diff --git a/ext/intl/tests/calendar_getTimeZone_error.phpt b/ext/intl/tests/calendar_getTimeZone_error.phpt deleted file mode 100644 index fad3a5e7e74..00000000000 --- a/ext/intl/tests/calendar_getTimeZone_error.phpt +++ /dev/null @@ -1,18 +0,0 @@ ---TEST-- -IntlCalendar::getTimeZone(): bad arguments ---INI-- -date.timezone=Atlantic/Azores ---EXTENSIONS-- -intl ---FILE-- - ---EXPECTF-- -Fatal error: Uncaught TypeError: intlcal_get_time_zone(): Argument #1 ($calendar) must be of type IntlCalendar, int given in %s:%d -Stack trace: -#0 %s(%d): intlcal_get_time_zone(1) -#1 {main} - thrown in %s on line %d diff --git a/ext/intl/tests/calendar_getTime_basic.phpt b/ext/intl/tests/calendar_getTime_basic.phpt index 97e31011e76..754dfde0147 100644 --- a/ext/intl/tests/calendar_getTime_basic.phpt +++ b/ext/intl/tests/calendar_getTime_basic.phpt @@ -1,13 +1,9 @@ --TEST-- IntlCalendar::getTime() basic test ---INI-- -date.timezone=Atlantic/Azores --EXTENSIONS-- intl --FILE-- clear(); @@ -22,4 +18,4 @@ var_dump((float)$time*1000, $intlcal->getTime()); ?> --EXPECT-- float(1330473600000) -float(1330473600000) \ No newline at end of file +float(1330473600000) diff --git a/ext/intl/tests/calendar_getTime_error.phpt b/ext/intl/tests/calendar_getTime_error.phpt deleted file mode 100644 index 0f6a470637b..00000000000 --- a/ext/intl/tests/calendar_getTime_error.phpt +++ /dev/null @@ -1,18 +0,0 @@ ---TEST-- -IntlCalendar::getTime(): bad arguments ---INI-- -date.timezone=Atlantic/Azores ---EXTENSIONS-- -intl ---FILE-- - ---EXPECTF-- -Fatal error: Uncaught TypeError: intlcal_get_time(): Argument #1 ($calendar) must be of type IntlCalendar, int given in %s:%d -Stack trace: -#0 %s(%d): intlcal_get_time(1) -#1 {main} - thrown in %s on line %d diff --git a/ext/intl/tests/calendar_getType_basic.phpt b/ext/intl/tests/calendar_getType_basic.phpt index c1ae1d242cd..bca65507ead 100644 --- a/ext/intl/tests/calendar_getType_basic.phpt +++ b/ext/intl/tests/calendar_getType_basic.phpt @@ -1,19 +1,15 @@ --TEST-- IntlCalendar::getType() basic test ---INI-- -date.timezone=Atlantic/Azores --EXTENSIONS-- intl --FILE-- getType()); +var_dump($intlcal->getType()); $intlcal = IntlCalendar::createInstance(null, "nl_NL@calendar=hebrew"); -VAR_DUMP(intlcal_get_type($intlcal)); +var_dump(intlcal_get_type($intlcal)); ?> --EXPECT-- string(9) "gregorian" -string(6) "hebrew" \ No newline at end of file +string(6) "hebrew" diff --git a/ext/intl/tests/calendar_getType_error.phpt b/ext/intl/tests/calendar_getType_error.phpt deleted file mode 100644 index 78d0a57f154..00000000000 --- a/ext/intl/tests/calendar_getType_error.phpt +++ /dev/null @@ -1,18 +0,0 @@ ---TEST-- -IntlCalendar::getType(): bad arguments ---INI-- -date.timezone=Atlantic/Azores ---EXTENSIONS-- -intl ---FILE-- - ---EXPECTF-- -Fatal error: Uncaught TypeError: intlcal_get_type(): Argument #1 ($calendar) must be of type IntlCalendar, int given in %s:%d -Stack trace: -#0 %s(%d): intlcal_get_type(1) -#1 {main} - thrown in %s on line %d diff --git a/ext/intl/tests/calendar_getWeekendTransition_basic.phpt b/ext/intl/tests/calendar_getWeekendTransition_basic.phpt index 2045dc6e341..4e5cfd41f4c 100644 --- a/ext/intl/tests/calendar_getWeekendTransition_basic.phpt +++ b/ext/intl/tests/calendar_getWeekendTransition_basic.phpt @@ -6,8 +6,6 @@ date.timezone=Atlantic/Azores intl --FILE-- getWeekendTransition(IntlCalendar::DOW_SUNDAY)); diff --git a/ext/intl/tests/calendar_getWeekendTransition_error.phpt b/ext/intl/tests/calendar_getWeekendTransition_error.phpt index 9bd269c9a08..a5e020a6803 100644 --- a/ext/intl/tests/calendar_getWeekendTransition_error.phpt +++ b/ext/intl/tests/calendar_getWeekendTransition_error.phpt @@ -1,12 +1,9 @@ --TEST-- IntlCalendar::getWeekendTransition(): bad arguments ---INI-- -date.timezone=Atlantic/Azores --EXTENSIONS-- intl --FILE-- getMessage() . \PHP_EOL; } -try { - var_dump(intlcal_get_weekend_transition(1, 1)); -} catch (\TypeError $e) { - echo $e->getMessage() . \PHP_EOL; -} - ?> --EXPECT-- IntlCalendar::getWeekendTransition(): Argument #1 ($dayOfWeek) must be a valid day of the week -intlcal_get_weekend_transition(): Argument #1 ($calendar) must be of type IntlCalendar, int given diff --git a/ext/intl/tests/calendar_getXMaximum_basic.phpt b/ext/intl/tests/calendar_getXMaximum_basic.phpt index 5e5ae778b2d..35b8a202d39 100644 --- a/ext/intl/tests/calendar_getXMaximum_basic.phpt +++ b/ext/intl/tests/calendar_getXMaximum_basic.phpt @@ -1,13 +1,9 @@ --TEST-- IntlCalendar::getMaximum(), ::getActualMaximum(), ::getLeastMaximum() basic test ---INI-- -date.timezone=Atlantic/Azores --EXTENSIONS-- intl --FILE-- setTime(strtotime('2012-02-29 05:06:07 +0000') * 1000); @@ -27,4 +23,4 @@ int(28) int(29) int(29) int(31) -int(31) \ No newline at end of file +int(31) diff --git a/ext/intl/tests/calendar_getXMinimum_basic.phpt b/ext/intl/tests/calendar_getXMinimum_basic.phpt index c8b6c2e9787..671acc6806a 100644 --- a/ext/intl/tests/calendar_getXMinimum_basic.phpt +++ b/ext/intl/tests/calendar_getXMinimum_basic.phpt @@ -1,13 +1,9 @@ --TEST-- IntlCalendar::getMinimum(), ::getActualMinimum(), ::getGreatestMinimum() basic test ---INI-- -date.timezone=Atlantic/Azores --EXTENSIONS-- intl --FILE-- setTime(strtotime('2012-02-29 05:06:07 +0000') * 1000); @@ -27,4 +23,4 @@ int(1) int(1) int(1) int(1) -int(1) \ No newline at end of file +int(1) diff --git a/ext/intl/tests/calendar_get_Least_Greatest_Minimum_Maximum_error.phpt b/ext/intl/tests/calendar_get_Least_Greatest_Minimum_Maximum_error.phpt index 1cab590955d..30365162820 100644 --- a/ext/intl/tests/calendar_get_Least_Greatest_Minimum_Maximum_error.phpt +++ b/ext/intl/tests/calendar_get_Least_Greatest_Minimum_Maximum_error.phpt @@ -1,7 +1,5 @@ --TEST-- IntlCalendar::get/Least/Greatest/Minimum/Maximum(): bad arguments ---INI-- -date.timezone=Atlantic/Azores --EXTENSIONS-- intl --FILE-- @@ -51,26 +49,6 @@ try { echo get_class($e) . ': ' . $e->getCode() . ', ' . $e->getMessage() . \PHP_EOL; } -try { - var_dump(intlcal_get_least_maximum(1, 1)); -} catch (Error $e) { - echo get_class($e) . ': ' . $e->getCode() . ', ' . $e->getMessage() . \PHP_EOL; -} -try { - var_dump(intlcal_get_maximum(1, 1)); -} catch (Error $e) { - echo get_class($e) . ': ' . $e->getCode() . ', ' . $e->getMessage() . \PHP_EOL; -} -try { - var_dump(intlcal_get_greatest_minimum(1, -1)); -} catch (Error $e) { - echo get_class($e) . ': ' . $e->getCode() . ', ' . $e->getMessage() . \PHP_EOL; -} -try { - var_dump(intlcal_get_minimum(1, -1)); -} catch (Error $e) { - echo get_class($e) . ': ' . $e->getCode() . ', ' . $e->getMessage() . \PHP_EOL; -} ?> --EXPECT-- ValueError: 0, IntlCalendar::getLeastMaximum(): Argument #1 ($field) must be a valid field @@ -81,7 +59,3 @@ ValueError: 0, intlcal_get_least_maximum(): Argument #2 ($field) must be a valid ValueError: 0, intlcal_get_maximum(): Argument #2 ($field) must be a valid field ValueError: 0, intlcal_get_greatest_minimum(): Argument #2 ($field) must be a valid field ValueError: 0, intlcal_get_minimum(): Argument #2 ($field) must be a valid field -TypeError: 0, intlcal_get_least_maximum(): Argument #1 ($calendar) must be of type IntlCalendar, int given -TypeError: 0, intlcal_get_maximum(): Argument #1 ($calendar) must be of type IntlCalendar, int given -TypeError: 0, intlcal_get_greatest_minimum(): Argument #1 ($calendar) must be of type IntlCalendar, int given -TypeError: 0, intlcal_get_minimum(): Argument #1 ($calendar) must be of type IntlCalendar, int given diff --git a/ext/intl/tests/calendar_get_basic.phpt b/ext/intl/tests/calendar_get_basic.phpt index b22092010b3..37a61b83d0b 100644 --- a/ext/intl/tests/calendar_get_basic.phpt +++ b/ext/intl/tests/calendar_get_basic.phpt @@ -4,8 +4,6 @@ IntlCalendar::get() basic test intl --FILE-- set(IntlCalendar::FIELD_DAY_OF_MONTH, 4); @@ -16,4 +14,4 @@ var_dump(intlcal_get($intlcal, IntlCalendar::FIELD_DAY_OF_MONTH)); ?> --EXPECT-- int(4) -int(4) \ No newline at end of file +int(4) diff --git a/ext/intl/tests/calendar_get_getActualMaximum_Minumum_error.phpt b/ext/intl/tests/calendar_get_getActualMaximum_Minumum_error.phpt index 9d40f9ec104..475c0640222 100644 --- a/ext/intl/tests/calendar_get_getActualMaximum_Minumum_error.phpt +++ b/ext/intl/tests/calendar_get_getActualMaximum_Minumum_error.phpt @@ -1,7 +1,5 @@ --TEST-- IntlCalendar::get/getActualMaximum/getActualMinimum(): bad arguments ---INI-- -date.timezone=Atlantic/Azores --EXTENSIONS-- intl --FILE-- diff --git a/ext/intl/tests/calendar_get_getActualMaximum_Minumum_error2.phpt b/ext/intl/tests/calendar_get_getActualMaximum_Minumum_error2.phpt index 0cfb77a8947..10eb7f8029b 100644 --- a/ext/intl/tests/calendar_get_getActualMaximum_Minumum_error2.phpt +++ b/ext/intl/tests/calendar_get_getActualMaximum_Minumum_error2.phpt @@ -1,7 +1,5 @@ --TEST-- IntlCalendar::get/getActualMaximum/getActualMinimum(): bad arguments (procedural) ---INI-- -date.timezone=Atlantic/Azores --EXTENSIONS-- intl --FILE-- @@ -9,22 +7,6 @@ intl $c = new IntlGregorianCalendar(NULL, 'pt_PT'); -try { - var_dump(intlcal_get($c)); -} catch (Error $e) { - echo get_class($e) . ': ' . $e->getCode() . ', ' . $e->getMessage() . \PHP_EOL; -} -try { - var_dump(intlcal_get_actual_maximum($c)); -} catch (Error $e) { - echo get_class($e) . ': ' . $e->getCode() . ', ' . $e->getMessage() . \PHP_EOL; -} -try { - var_dump(intlcal_get_actual_minimum($c)); -} catch (Error $e) { - echo get_class($e) . ': ' . $e->getCode() . ', ' . $e->getMessage() . \PHP_EOL; -} - try { var_dump(intlcal_get($c, -1)); } catch (Error $e) { @@ -41,48 +23,8 @@ try { echo get_class($e) . ': ' . $e->getCode() . ', ' . $e->getMessage() . \PHP_EOL; } -try { - var_dump(intlcal_get($c, "s")); -} catch (Error $e) { - echo get_class($e) . ': ' . $e->getCode() . ', ' . $e->getMessage() . \PHP_EOL; -} -try { - var_dump(intlcal_get_actual_maximum($c, "s")); -} catch (Error $e) { - echo get_class($e) . ': ' . $e->getCode() . ', ' . $e->getMessage() . \PHP_EOL; -} -try { - var_dump(intlcal_get_actual_minimum($c, "s")); -} catch (Error $e) { - echo get_class($e) . ': ' . $e->getCode() . ', ' . $e->getMessage() . \PHP_EOL; -} - -try { - var_dump(intlcal_get(1)); -} catch (Error $e) { - echo get_class($e) . ': ' . $e->getCode() . ', ' . $e->getMessage() . \PHP_EOL; -} -try { - var_dump(intlcal_get_actual_maximum(1)); -} catch (Error $e) { - echo get_class($e) . ': ' . $e->getCode() . ', ' . $e->getMessage() . \PHP_EOL; -} -try { - var_dump(intlcal_get_actual_minimum(1)); -} catch (Error $e) { - echo get_class($e) . ': ' . $e->getCode() . ', ' . $e->getMessage() . \PHP_EOL; -} ?> --EXPECT-- -ArgumentCountError: 0, intlcal_get() expects exactly 2 arguments, 1 given -ArgumentCountError: 0, intlcal_get_actual_maximum() expects exactly 2 arguments, 1 given -ArgumentCountError: 0, intlcal_get_actual_minimum() expects exactly 2 arguments, 1 given ValueError: 0, intlcal_get(): Argument #2 ($field) must be a valid field ValueError: 0, intlcal_get_actual_maximum(): Argument #2 ($field) must be a valid field ValueError: 0, intlcal_get_actual_minimum(): Argument #2 ($field) must be a valid field -TypeError: 0, intlcal_get(): Argument #2 ($field) must be of type int, string given -TypeError: 0, intlcal_get_actual_maximum(): Argument #2 ($field) must be of type int, string given -TypeError: 0, intlcal_get_actual_minimum(): Argument #2 ($field) must be of type int, string given -ArgumentCountError: 0, intlcal_get() expects exactly 2 arguments, 1 given -ArgumentCountError: 0, intlcal_get_actual_maximum() expects exactly 2 arguments, 1 given -ArgumentCountError: 0, intlcal_get_actual_minimum() expects exactly 2 arguments, 1 given diff --git a/ext/intl/tests/calendar_get_setRepeatedWallTimeOption_basic.phpt b/ext/intl/tests/calendar_get_setRepeatedWallTimeOption_basic.phpt index 146885b3770..249f39b7f19 100644 --- a/ext/intl/tests/calendar_get_setRepeatedWallTimeOption_basic.phpt +++ b/ext/intl/tests/calendar_get_setRepeatedWallTimeOption_basic.phpt @@ -2,12 +2,11 @@ IntlCalendar::get/setRepeatedWallTimeOption(): basic test --EXTENSIONS-- intl +--INI-- +intl.default_locale=nl +date.timezone=Europe/Amsterdam --FILE-- setTime(strtotime('2012-01-01') * 1000); @@ -17,4 +13,4 @@ var_dump(intlcal_in_daylight_time($intlcal)); ?> --EXPECT-- bool(false) -bool(true) \ No newline at end of file +bool(true) diff --git a/ext/intl/tests/calendar_inDaylightTime_error.phpt b/ext/intl/tests/calendar_inDaylightTime_error.phpt deleted file mode 100644 index 7dd6d9c8803..00000000000 --- a/ext/intl/tests/calendar_inDaylightTime_error.phpt +++ /dev/null @@ -1,18 +0,0 @@ ---TEST-- -IntlCalendar::inDaylightTime(): bad arguments ---INI-- -date.timezone=Atlantic/Azores ---EXTENSIONS-- -intl ---FILE-- - ---EXPECTF-- -Fatal error: Uncaught TypeError: intlcal_in_daylight_time(): Argument #1 ($calendar) must be of type IntlCalendar, int given in %s:%d -Stack trace: -#0 %s(%d): intlcal_in_daylight_time(1) -#1 {main} - thrown in %s on line %d diff --git a/ext/intl/tests/calendar_isEquivalentTo_basic.phpt b/ext/intl/tests/calendar_isEquivalentTo_basic.phpt index e9c0a6ec575..bb01fcfa1f9 100644 --- a/ext/intl/tests/calendar_isEquivalentTo_basic.phpt +++ b/ext/intl/tests/calendar_isEquivalentTo_basic.phpt @@ -4,8 +4,6 @@ IntlCalendar::isEquivalentTo() basic test intl --FILE-- isEquivalentTo(0)); -} catch (Error $ex) { - echo "error: " . $ex->getCode() . ", " . $ex->getMessage() . "\n\n"; -} -try { - var_dump($c->isEquivalentTo($c, 1)); -} catch (Error $ex) { - echo "error: " . $ex->getCode() . ", " . $ex->getMessage() . "\n\n"; -} -try { - var_dump($c->isEquivalentTo(1)); -} catch (Error $ex) { - echo "error: " . $ex->getCode() . ", " . $ex->getMessage() . "\n\n"; -} - -try { - var_dump(intlcal_is_equivalent_to($c)); -} catch (Error $ex) { - echo "error: " . $ex->getCode() . ", " . $ex->getMessage() . "\n\n"; -} -try { - var_dump(intlcal_is_equivalent_to($c, 1)); -} catch (Error $ex) { - echo "error: " . $ex->getCode() . ", " . $ex->getMessage() . "\n\n"; -} -try { - var_dump(intlcal_is_equivalent_to(1, $c)); -} catch (Error $ex) { - echo "error: " . $ex->getCode() . ", " . $ex->getMessage() . "\n\n"; -} -?> ---EXPECT-- -error: 0, IntlCalendar::isEquivalentTo(): Argument #1 ($other) must be of type IntlCalendar, int given - -error: 0, IntlCalendar::isEquivalentTo() expects exactly 1 argument, 2 given - -error: 0, IntlCalendar::isEquivalentTo(): Argument #1 ($other) must be of type IntlCalendar, int given - -error: 0, intlcal_is_equivalent_to() expects exactly 2 arguments, 1 given - -error: 0, intlcal_is_equivalent_to(): Argument #2 ($other) must be of type IntlCalendar, int given - -error: 0, intlcal_is_equivalent_to(): Argument #1 ($calendar) must be of type IntlCalendar, int given diff --git a/ext/intl/tests/calendar_isLenient_error.phpt b/ext/intl/tests/calendar_isLenient_error.phpt deleted file mode 100644 index 4011c11cdd8..00000000000 --- a/ext/intl/tests/calendar_isLenient_error.phpt +++ /dev/null @@ -1,18 +0,0 @@ ---TEST-- -IntlCalendar::isLenient(): bad arguments ---INI-- -date.timezone=Atlantic/Azores ---EXTENSIONS-- -intl ---FILE-- - ---EXPECTF-- -Fatal error: Uncaught TypeError: intlcal_is_lenient(): Argument #1 ($calendar) must be of type IntlCalendar, int given in %s:%d -Stack trace: -#0 %s(%d): intlcal_is_lenient(1) -#1 {main} - thrown in %s on line %d diff --git a/ext/intl/tests/calendar_isSet_basic.phpt b/ext/intl/tests/calendar_isSet_basic.phpt index 69895d9e93d..2f6a8b22a39 100644 --- a/ext/intl/tests/calendar_isSet_basic.phpt +++ b/ext/intl/tests/calendar_isSet_basic.phpt @@ -4,8 +4,6 @@ IntlCalendar::isSet() basic test intl --FILE-- isSet(IntlCalendar::FIELD_MINUTE)); @@ -17,4 +15,4 @@ var_dump(intlcal_is_set($intlcal, IntlCalendar::FIELD_MINUTE)); --EXPECT-- bool(true) bool(false) -bool(true) \ No newline at end of file +bool(true) diff --git a/ext/intl/tests/calendar_isSet_error.phpt b/ext/intl/tests/calendar_isSet_error.phpt index 9f1361b8dce..7f289f073ae 100644 --- a/ext/intl/tests/calendar_isSet_error.phpt +++ b/ext/intl/tests/calendar_isSet_error.phpt @@ -1,7 +1,5 @@ --TEST-- IntlCalendar::isSet(): bad arguments ---INI-- -date.timezone=Atlantic/Azores --EXTENSIONS-- intl --FILE-- @@ -15,12 +13,6 @@ try { echo $e->getMessage() . \PHP_EOL; } -try { - var_dump(intlcal_is_set(1, 2)); -} catch (\TypeError $e) { - echo $e->getMessage() . \PHP_EOL; -} ?> --EXPECT-- IntlCalendar::isSet(): Argument #1 ($field) must be a valid field -intlcal_is_set(): Argument #1 ($calendar) must be of type IntlCalendar, int given diff --git a/ext/intl/tests/calendar_isWeekend_basic.phpt b/ext/intl/tests/calendar_isWeekend_basic.phpt index 83408b6283b..9479bdc0298 100644 --- a/ext/intl/tests/calendar_isWeekend_basic.phpt +++ b/ext/intl/tests/calendar_isWeekend_basic.phpt @@ -1,13 +1,9 @@ --TEST-- IntlCalendar::isWeekend basic test ---INI-- -date.timezone=Atlantic/Azores --EXTENSIONS-- intl --FILE-- isWeekend(strtotime('2012-02-29 12:00:00 +0000') * 1000)); diff --git a/ext/intl/tests/calendar_isWeekend_error.phpt b/ext/intl/tests/calendar_isWeekend_error.phpt deleted file mode 100644 index d1d49149bf1..00000000000 --- a/ext/intl/tests/calendar_isWeekend_error.phpt +++ /dev/null @@ -1,18 +0,0 @@ ---TEST-- -IntlCalendar::isWeekend(): bad arguments ---INI-- -date.timezone=Atlantic/Azores ---EXTENSIONS-- -intl ---FILE-- - ---EXPECTF-- -Fatal error: Uncaught TypeError: intlcal_is_weekend(): Argument #1 ($calendar) must be of type IntlCalendar, int given in %s:%d -Stack trace: -#0 %s(%d): intlcal_is_weekend(1) -#1 {main} - thrown in %s on line %d diff --git a/ext/intl/tests/calendar_is_set_lenient_basic.phpt b/ext/intl/tests/calendar_is_set_lenient_basic.phpt index 4ec0d8cd01e..e516050f27f 100644 --- a/ext/intl/tests/calendar_is_set_lenient_basic.phpt +++ b/ext/intl/tests/calendar_is_set_lenient_basic.phpt @@ -4,8 +4,6 @@ IntlCalendar::isLenient(), ::setLenient() basic test intl --FILE-- isLenient()); @@ -21,4 +19,4 @@ bool(true) bool(true) bool(false) bool(true) -bool(true) \ No newline at end of file +bool(true) diff --git a/ext/intl/tests/calendar_roll_basic.phpt b/ext/intl/tests/calendar_roll_basic.phpt index 3a77bafec3e..a8b088ec384 100644 --- a/ext/intl/tests/calendar_roll_basic.phpt +++ b/ext/intl/tests/calendar_roll_basic.phpt @@ -6,8 +6,6 @@ date.timezone=Atlantic/Azores intl --FILE-- roll(IntlCalendar::FIELD_DAY_OF_MONTH, 2)); diff --git a/ext/intl/tests/calendar_roll_error.phpt b/ext/intl/tests/calendar_roll_error.phpt index 721297f0458..4c05c17a5f8 100644 --- a/ext/intl/tests/calendar_roll_error.phpt +++ b/ext/intl/tests/calendar_roll_error.phpt @@ -1,7 +1,5 @@ --TEST-- IntlCalendar::roll(): bad arguments ---INI-- -date.timezone=Atlantic/Azores --EXTENSIONS-- intl --FILE-- @@ -15,12 +13,6 @@ try { echo $e->getMessage() . \PHP_EOL; } -try { - var_dump(intlcal_roll(1, 2, 3)); -} catch (\TypeError $e) { - echo $e->getMessage() . \PHP_EOL; -} ?> --EXPECT-- IntlCalendar::roll(): Argument #1 ($field) must be a valid field -intlcal_roll(): Argument #1 ($calendar) must be of type IntlCalendar, int given diff --git a/ext/intl/tests/calendar_roll_variation1.phpt b/ext/intl/tests/calendar_roll_variation1.phpt index a496d6f2e54..d79d5dbb598 100644 --- a/ext/intl/tests/calendar_roll_variation1.phpt +++ b/ext/intl/tests/calendar_roll_variation1.phpt @@ -6,8 +6,6 @@ date.timezone=Atlantic/Azores intl --FILE-- roll(IntlCalendar::FIELD_DAY_OF_MONTH, true)); diff --git a/ext/intl/tests/calendar_setFirstDayOfWeek_basic.phpt b/ext/intl/tests/calendar_setFirstDayOfWeek_basic.phpt index 88b2d53ca6c..a77b00ce640 100644 --- a/ext/intl/tests/calendar_setFirstDayOfWeek_basic.phpt +++ b/ext/intl/tests/calendar_setFirstDayOfWeek_basic.phpt @@ -4,8 +4,6 @@ IntlCalendar::setFirstDayOfWeek() basic test intl --FILE-- getMessage() . \PHP_EOL; } -try { - var_dump(intlcal_set_first_day_of_week(1, 2)); -} catch (\TypeError $e) { - echo $e->getMessage() . \PHP_EOL; -} ?> --EXPECT-- IntlCalendar::setFirstDayOfWeek(): Argument #1 ($dayOfWeek) must be a valid day of the week intlcal_set_first_day_of_week(): Argument #2 ($dayOfWeek) must be a valid day of the week -intlcal_set_first_day_of_week(): Argument #1 ($calendar) must be of type IntlCalendar, int given diff --git a/ext/intl/tests/calendar_setLenient_error.phpt b/ext/intl/tests/calendar_setLenient_error.phpt deleted file mode 100644 index 13ecebc5fd5..00000000000 --- a/ext/intl/tests/calendar_setLenient_error.phpt +++ /dev/null @@ -1,18 +0,0 @@ ---TEST-- -IntlCalendar::setLenient(): bad arguments ---INI-- -date.timezone=Atlantic/Azores ---EXTENSIONS-- -intl ---FILE-- - ---EXPECTF-- -Fatal error: Uncaught TypeError: intlcal_set_lenient(): Argument #1 ($calendar) must be of type IntlCalendar, int given in %s:%d -Stack trace: -#0 %s(%d): intlcal_set_lenient(1, false) -#1 {main} - thrown in %s on line %d diff --git a/ext/intl/tests/calendar_setMinimalDaysInFirstWeek_basic.phpt b/ext/intl/tests/calendar_setMinimalDaysInFirstWeek_basic.phpt index 7d47f315ae0..5ac2eb58999 100644 --- a/ext/intl/tests/calendar_setMinimalDaysInFirstWeek_basic.phpt +++ b/ext/intl/tests/calendar_setMinimalDaysInFirstWeek_basic.phpt @@ -4,8 +4,6 @@ IntlCalendar::setMinimalDaysInFirstWeek() basic test intl --FILE-- getMessage() . \PHP_EOL; } -try { - var_dump(intlcal_set_minimal_days_in_first_week(1, 2)); -} catch (\TypeError $e) { - echo $e->getMessage() . \PHP_EOL; -} ?> --EXPECT-- IntlCalendar::setMinimalDaysInFirstWeek(): Argument #1 ($days) must be between 1 and 7 intlcal_set_minimal_days_in_first_week(): Argument #2 ($days) must be between 1 and 7 -intlcal_set_minimal_days_in_first_week(): Argument #1 ($calendar) must be of type IntlCalendar, int given diff --git a/ext/intl/tests/calendar_setSkipped_RepeatedWallTimeOption_error.phpt b/ext/intl/tests/calendar_setSkipped_RepeatedWallTimeOption_error.phpt index 0e3c10d7f55..8019c81870d 100644 --- a/ext/intl/tests/calendar_setSkipped_RepeatedWallTimeOption_error.phpt +++ b/ext/intl/tests/calendar_setSkipped_RepeatedWallTimeOption_error.phpt @@ -1,12 +1,9 @@ --TEST-- IntlCalendar::setSkipped/RepeatedWallTimeOption(): bad arguments ---INI-- -date.timezone=Atlantic/Azores --EXTENSIONS-- intl --FILE-- getMessage() . \PHP_EOL; } -try { - var_dump(intlcal_set_repeated_wall_time_option(1, 1)); -} catch (\TypeError $e) { - echo $e->getMessage() . \PHP_EOL; -} ?> --EXPECT-- IntlCalendar::setSkippedWallTimeOption(): Argument #1 ($option) must be one of IntlCalendar::WALLTIME_FIRST, IntlCalendar::WALLTIME_LAST, or IntlCalendar::WALLTIME_NEXT_VALID IntlCalendar::setRepeatedWallTimeOption(): Argument #1 ($option) must be either IntlCalendar::WALLTIME_FIRST or IntlCalendar::WALLTIME_LAST -intlcal_set_repeated_wall_time_option(): Argument #1 ($calendar) must be of type IntlCalendar, int given diff --git a/ext/intl/tests/calendar_setTimeZone_basic.phpt b/ext/intl/tests/calendar_setTimeZone_basic.phpt index aacc384087d..bd0be9e8781 100644 --- a/ext/intl/tests/calendar_setTimeZone_basic.phpt +++ b/ext/intl/tests/calendar_setTimeZone_basic.phpt @@ -4,8 +4,6 @@ IntlCalendar::setTimeZone() basic test intl --FILE-- getTimeZone()->getID()); diff --git a/ext/intl/tests/calendar_setTimeZone_error.phpt b/ext/intl/tests/calendar_setTimeZone_error.phpt deleted file mode 100644 index 0cf7939e2de..00000000000 --- a/ext/intl/tests/calendar_setTimeZone_error.phpt +++ /dev/null @@ -1,49 +0,0 @@ ---TEST-- -IntlCalendar::setTimeZone(): bad arguments ---INI-- -date.timezone=Atlantic/Azores ---EXTENSIONS-- -intl ---FILE-- -setTimeZone($gmt, 2)); -} catch (Error $ex) { - echo "error: " . $ex->getCode() . ", " . $ex->getMessage() . "\n\n"; -} -try { - var_dump($c->setTimeZone()); -} catch (Error $ex) { - echo "error: " . $ex->getCode() . ", " . $ex->getMessage() . "\n\n"; -} - -try{ - var_dump(intlcal_set_time_zone($c, 1, 2)); -} catch (Error $ex) { - echo "error: " . $ex->getCode() . ", " . $ex->getMessage() . "\n\n"; -} -try{ - var_dump(intlcal_set_time_zone(1, $gmt)); -} catch (Error $ex) { - echo "error: " . $ex->getCode() . ", " . $ex->getMessage() . "\n\n"; -} -?> ---EXPECT-- -error: 0, IntlCalendar::setTimeZone() expects exactly 1 argument, 2 given - -error: 0, IntlCalendar::setTimeZone() expects exactly 1 argument, 0 given - -error: 0, intlcal_set_time_zone() expects exactly 2 arguments, 3 given - -error: 0, intlcal_set_time_zone(): Argument #1 ($calendar) must be of type IntlCalendar, int given diff --git a/ext/intl/tests/calendar_setTimeZone_error2.phpt b/ext/intl/tests/calendar_setTimeZone_error2.phpt index c76867b695e..6b65aa1a0e7 100644 --- a/ext/intl/tests/calendar_setTimeZone_error2.phpt +++ b/ext/intl/tests/calendar_setTimeZone_error2.phpt @@ -2,25 +2,28 @@ IntlCalendar::setTimeZone(): valid time zones for DateTime but not ICU --EXTENSIONS-- intl +--INI-- +date.timezone=Europe/Amsterdam +intl.default_locale=nl --FILE-- setTimeZone($pstdate->getTimeZone()); +var_dump($intlcal->setTimeZone($pstdate->getTimeZone())); +var_dump($intlcal->getErrorMessage()); var_dump($intlcal->getTimeZone()->getID()); $pstdate = new DateTime('2012-01-01 00:00:00 +24:00'); -$intlcal->setTimeZone($pstdate->getTimeZone()); +var_dump($intlcal->setTimeZone($pstdate->getTimeZone())); +var_dump($intlcal->getErrorMessage()); var_dump($intlcal->getTimeZone()->getID()); ?> ---EXPECTF-- -Warning: IntlCalendar::setTimeZone(): intlcal_set_time_zone: time zone id 'WEST' extracted from ext/date DateTimeZone not recognized in %s on line %d +--EXPECT-- +bool(false) +string(126) "IntlCalendar::setTimeZone(): time zone id 'WEST' extracted from ext/date DateTimeZone not recognized: U_ILLEGAL_ARGUMENT_ERROR" string(16) "Europe/Amsterdam" - -Warning: IntlCalendar::setTimeZone(): intlcal_set_time_zone: object has an time zone offset that's too large in %s on line %d +bool(false) +string(102) "IntlCalendar::setTimeZone(): object has an time zone offset that's too large: U_ILLEGAL_ARGUMENT_ERROR" string(16) "Europe/Amsterdam" diff --git a/ext/intl/tests/calendar_setTimeZone_variation1.phpt b/ext/intl/tests/calendar_setTimeZone_variation1.phpt index 820fd2fd21c..01d933b9b9a 100644 --- a/ext/intl/tests/calendar_setTimeZone_variation1.phpt +++ b/ext/intl/tests/calendar_setTimeZone_variation1.phpt @@ -4,8 +4,6 @@ IntlCalendar::setTimeZone() variation with NULL arg intl --FILE-- getTimeZone()->getID()); @@ -23,4 +21,4 @@ var_dump($intlcal->get(IntlCalendar::FIELD_ZONE_OFFSET)); Europe/Amsterdam int(3600000) Europe/Amsterdam -int(3600000) \ No newline at end of file +int(3600000) diff --git a/ext/intl/tests/calendar_setTimeZone_variation2.phpt b/ext/intl/tests/calendar_setTimeZone_variation2.phpt index 25ec03c1f57..e9866e88c68 100644 --- a/ext/intl/tests/calendar_setTimeZone_variation2.phpt +++ b/ext/intl/tests/calendar_setTimeZone_variation2.phpt @@ -4,9 +4,6 @@ IntlCalendar::setTimeZone(): different ways to specify time zone intl --FILE-- setTimeZone('Europe/Paris'); diff --git a/ext/intl/tests/calendar_setTime_basic.phpt b/ext/intl/tests/calendar_setTime_basic.phpt index 41f3e0a964e..045d312e860 100644 --- a/ext/intl/tests/calendar_setTime_basic.phpt +++ b/ext/intl/tests/calendar_setTime_basic.phpt @@ -1,13 +1,9 @@ --TEST-- IntlCalendar::setTime() basic test ---INI-- -date.timezone=Atlantic/Azores --EXTENSIONS-- intl --FILE-- ---EXPECTF-- -Fatal error: Uncaught ArgumentCountError: intlcal_set_time() expects exactly 2 arguments, 1 given in %s:%d -Stack trace: -#0 %s(%d): intlcal_set_time(1) -#1 {main} - thrown in %s on line %d diff --git a/ext/intl/tests/calendar_set_basic.phpt b/ext/intl/tests/calendar_set_basic.phpt index 8c410bc3b75..1cd946fdd3c 100644 --- a/ext/intl/tests/calendar_set_basic.phpt +++ b/ext/intl/tests/calendar_set_basic.phpt @@ -6,8 +6,6 @@ date.timezone=Atlantic/Azores intl --FILE-- set(IntlCalendar::FIELD_DAY_OF_MONTH, 2)); diff --git a/ext/intl/tests/calendar_set_error.phpt b/ext/intl/tests/calendar_set_error.phpt index 4494c67c954..d29442f5195 100644 --- a/ext/intl/tests/calendar_set_error.phpt +++ b/ext/intl/tests/calendar_set_error.phpt @@ -1,12 +1,9 @@ --TEST-- IntlCalendar::set(): bad arguments ---INI-- -date.timezone=Atlantic/Azores --EXTENSIONS-- intl --FILE-- getMessage() . \PHP_EOL; } -try { - var_dump(intlcal_set(1, 2, 3)); -} catch (\TypeError $e) { - echo $e->getMessage() . \PHP_EOL; -} ?> --EXPECTF-- Deprecated: Calling IntlCalendar::set() with more than 2 arguments is deprecated, use either IntlCalendar::setDate() or IntlCalendar::setDateTime() instead in %s on line %d @@ -50,6 +42,3 @@ IntlCalendar::set(): Argument #1 ($year) must be a valid field Deprecated: Function intlcal_set() is deprecated since 8.4, use IntlCalendar::set(), IntlCalendar::setDate(), or IntlCalendar::setDateTime() instead in %s on line %d intlcal_set(): Argument #2 ($year) must be a valid field - -Deprecated: Function intlcal_set() is deprecated since 8.4, use IntlCalendar::set(), IntlCalendar::setDate(), or IntlCalendar::setDateTime() instead in %s on line %d -intlcal_set(): Argument #1 ($calendar) must be of type IntlCalendar, int given diff --git a/ext/intl/tests/calendar_set_variation1.phpt b/ext/intl/tests/calendar_set_variation1.phpt index 520c9094873..1d23a8d03c5 100644 --- a/ext/intl/tests/calendar_set_variation1.phpt +++ b/ext/intl/tests/calendar_set_variation1.phpt @@ -1,13 +1,9 @@ --TEST-- IntlCalendar::set() argument variations ---INI-- -date.timezone=Atlantic/Azores --EXTENSIONS-- intl --FILE-- clear(); diff --git a/ext/intl/tests/calendar_toDateTime_basic.phpt b/ext/intl/tests/calendar_toDateTime_basic.phpt index 391d13005c6..09942cbe3d8 100644 --- a/ext/intl/tests/calendar_toDateTime_basic.phpt +++ b/ext/intl/tests/calendar_toDateTime_basic.phpt @@ -2,11 +2,10 @@ IntlCalendar::toDateTime(): basic test --EXTENSIONS-- intl +--INI-- +date.timezone=Europe/Lisbon --FILE-- toDateTime()); -} catch (Exception $e) { -var_dump("exception: {$e->getMessage()}"); + var_dump($cal->toDateTime()); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; + $previous = $e->getPrevious(); + echo ' ', $previous::class, ': ', $previous->getMessage(), PHP_EOL; } try { var_dump(intlcal_to_date_time($cal)); -} catch (\Exception $e) { - var_dump($e->getMessage()); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; + $previous = $e->getPrevious(); + echo ' ', $previous::class, ': ', $previous->getMessage(), PHP_EOL; } $cal = IntlCalendar::createInstance("Etc/Unknown"); try { var_dump($cal->toDateTime()); -} catch (\Exception $e) { - var_dump($e->getMessage()); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; + $previous = $e->getPrevious(); + echo ' ', $previous::class, ': ', $previous->getMessage(), PHP_EOL; } try { var_dump(intlcal_to_date_time($cal)); -} catch (\Exception $e) { - var_dump($e->getMessage()); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; + $previous = $e->getPrevious(); + echo ' ', $previous::class, ': ', $previous->getMessage(), PHP_EOL; } -try { - var_dump(intlcal_to_date_time(3)); -} catch (\TypeError $e) { - echo $e->getMessage() . \PHP_EOL; -} ?> ---EXPECTF-- -Warning: IntlCalendar::toDateTime(): intlcal_to_date_time: DateTimeZone constructor threw exception in %s on line %d -string(77) "exception: DateTimeZone::__construct(): Unknown or bad timezone (Etc/Unknown)" - -Warning: intlcal_to_date_time(): intlcal_to_date_time: DateTimeZone constructor threw exception in %s on line %d -string(66) "DateTimeZone::__construct(): Unknown or bad timezone (Etc/Unknown)" - -Warning: IntlCalendar::toDateTime(): intlcal_to_date_time: DateTimeZone constructor threw exception in %s on line %d -string(66) "DateTimeZone::__construct(): Unknown or bad timezone (Etc/Unknown)" - -Warning: intlcal_to_date_time(): intlcal_to_date_time: DateTimeZone constructor threw exception in %s on line %d -string(66) "DateTimeZone::__construct(): Unknown or bad timezone (Etc/Unknown)" -intlcal_to_date_time(): Argument #1 ($calendar) must be of type IntlCalendar, int given +--EXPECT-- +IntlException: DateTimeZone constructor threw exception + DateInvalidTimeZoneException: DateTimeZone::__construct(): Unknown or bad timezone (Etc/Unknown) +IntlException: DateTimeZone constructor threw exception + DateInvalidTimeZoneException: DateTimeZone::__construct(): Unknown or bad timezone (Etc/Unknown) +IntlException: DateTimeZone constructor threw exception + DateInvalidTimeZoneException: DateTimeZone::__construct(): Unknown or bad timezone (Etc/Unknown) +IntlException: DateTimeZone constructor threw exception + DateInvalidTimeZoneException: DateTimeZone::__construct(): Unknown or bad timezone (Etc/Unknown) diff --git a/ext/intl/tests/collator_create4.phpt b/ext/intl/tests/collator_create.phpt similarity index 70% rename from ext/intl/tests/collator_create4.phpt rename to ext/intl/tests/collator_create.phpt index 5747d366dcf..2554571ba35 100644 --- a/ext/intl/tests/collator_create4.phpt +++ b/ext/intl/tests/collator_create.phpt @@ -1,5 +1,5 @@ --TEST-- -create() icu >= 53.1 +Collator creation tests --EXTENSIONS-- intl --FILE-- @@ -17,11 +17,9 @@ function ut_main() $locales = array( 'EN-US-ODESSA', 'UK_UA_ODESSA', - 'uk-ua_CALIFORNIA@currency=;currency=GRN', '', 'root', 'uk@currency=EURO', - '12345678911131517192123252729313335373941434547495153575961636567697173757779818385878991939597991234567891113151719212325272931333537394143454749515357596163656769717375777981838587899193959799' ); foreach( $locales as $locale ) @@ -62,7 +60,6 @@ Locale: 'UK_UA_ODESSA' ULOC_REQUESTED_LOCALE = 'UK_UA_ODESSA' ULOC_VALID_LOCALE = 'uk' ULOC_ACTUAL_LOCALE = 'uk' -Error creating collator with 'uk-ua_CALIFORNIA@currency=;currency=GRN' locale: collator_create: unable to open ICU collator: U_ILLEGAL_ARGUMENT_ERROR Locale: '' ULOC_REQUESTED_LOCALE = '' ULOC_VALID_LOCALE = '%s' @@ -75,4 +72,3 @@ Locale: 'uk@currency=EURO' ULOC_REQUESTED_LOCALE = 'uk@currency=EURO' ULOC_VALID_LOCALE = 'uk' ULOC_ACTUAL_LOCALE = 'uk' -Error creating collator with '12345678911131517192123252729313335373941434547495153575961636567697173757779818385878991939597991234567891113151719212325272931333537394143454749515357596163656769717375777981838587899193959799' locale: Locale string too long, should be no longer than %d characters: U_ILLEGAL_ARGUMENT_ERROR diff --git a/ext/intl/tests/collator_create_errors.phpt b/ext/intl/tests/collator_create_errors.phpt new file mode 100644 index 00000000000..41fc794f67c --- /dev/null +++ b/ext/intl/tests/collator_create_errors.phpt @@ -0,0 +1,40 @@ +--TEST-- +Collator creation errors +--EXTENSIONS-- +intl +--FILE-- +getMessage(), PHP_EOL; + } + + $c = Collator::create($locale); + var_dump($c); + var_dump(intl_get_error_message()); + + $c = collator_create($locale); + var_dump($c); + var_dump(intl_get_error_message()); +} + +?> +--EXPECT-- +IntlException: Collator::__construct(): unable to open ICU collator +NULL +string(73) "Collator::create(): unable to open ICU collator: U_ILLEGAL_ARGUMENT_ERROR" +NULL +string(72) "collator_create(): unable to open ICU collator: U_ILLEGAL_ARGUMENT_ERROR" +IntlException: Collator::__construct(): Locale string too long, should be no longer than 156 characters +NULL +string(109) "Collator::create(): Locale string too long, should be no longer than 156 characters: U_ILLEGAL_ARGUMENT_ERROR" +NULL +string(108) "collator_create(): Locale string too long, should be no longer than 156 characters: U_ILLEGAL_ARGUMENT_ERROR" diff --git a/ext/intl/tests/collation_customization.phpt b/ext/intl/tests/collator_customization.phpt similarity index 90% rename from ext/intl/tests/collation_customization.phpt rename to ext/intl/tests/collator_customization.phpt index aeb14386fd2..befb2c129e2 100644 --- a/ext/intl/tests/collation_customization.phpt +++ b/ext/intl/tests/collator_customization.phpt @@ -6,11 +6,10 @@ intl ---EXPECT-- -U_ZERO_ERROR -Error getting attribute value: U_ILLEGAL_ARGUMENT_ERROR diff --git a/ext/intl/tests/collator_get_invalid_attribute.phpt b/ext/intl/tests/collator_get_invalid_attribute.phpt new file mode 100644 index 00000000000..11a1e0ef9b6 --- /dev/null +++ b/ext/intl/tests/collator_get_invalid_attribute.phpt @@ -0,0 +1,23 @@ +--TEST-- +Collator get invalid attribute +--EXTENSIONS-- +intl +--FILE-- +getAttribute($attr)); +var_dump($coll->getErrorMessage()); + +var_dump(collator_get_attribute($coll, $attr)); +var_dump(collator_get_error_message($coll)); + +?> +--EXPECT-- +bool(false) +string(81) "Collator::getAttribute(): Error getting attribute value: U_ILLEGAL_ARGUMENT_ERROR" +bool(false) +string(81) "collator_get_attribute(): Error getting attribute value: U_ILLEGAL_ARGUMENT_ERROR" diff --git a/ext/intl/tests/cpbi_clone_equality.phpt b/ext/intl/tests/cpbi_clone_equality.phpt index 37f1998e257..caea9f8ba08 100644 --- a/ext/intl/tests/cpbi_clone_equality.phpt +++ b/ext/intl/tests/cpbi_clone_equality.phpt @@ -2,10 +2,10 @@ IntlCodePointBreakIterator: clone and equality --EXTENSIONS-- intl +--INI-- +intl.default_locale=pt_PT --FILE-- getMessage() . " in " . $e->getFile() . " on line " . $e->getLine() . "\n"; -} try { var_dump(new IntlDateFormatter(NULL, 0, 0, 'bad timezone')); -} catch (IntlException $e) { - print_exception($e); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } try { var_dump(new IntlDateFormatter(NULL, 0, 0, NULL, 3)); -} catch (IntlException $e) { - print_exception($e); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } try { var_dump(new IntlDateFormatter(NULL, 0, 0, NULL, new stdclass)); -} catch (TypeError $e) { - print_exception($e); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } ?> ---EXPECTF-- +--EXPECT-- +IntlException: IntlDateFormatter::__construct(): No such time zone: "bad timezone" +IntlException: IntlDateFormatter::__construct(): Invalid value for calendar type; it must be one of IntlDateFormatter::TRADITIONAL (locale's default calendar) or IntlDateFormatter::GREGORIAN. Alternatively, it can be an IntlCalendar object +TypeError: IntlDateFormatter::__construct(): Argument #5 ($calendar) must be of type IntlCalendar|int|null, stdClass given -Exception: datefmt_create: No such time zone: 'bad timezone' in %s on line %d - -Exception: IntlDateFormatter::__construct(): datefmt_create: Invalid value for calendar type; it must be one of IntlDateFormatter::TRADITIONAL (locale's default calendar) or IntlDateFormatter::GREGORIAN. Alternatively, it can be an IntlCalendar object in %s on line %d - -Exception: IntlDateFormatter::__construct(): Argument #5 ($calendar) must be of type IntlCalendar|int|null, stdClass given in %s on line %d diff --git a/ext/intl/tests/dateformat_bug68893.phpt b/ext/intl/tests/dateformat_bug68893.phpt index 341acd49a6d..b0510097fc5 100644 --- a/ext/intl/tests/dateformat_bug68893.phpt +++ b/ext/intl/tests/dateformat_bug68893.phpt @@ -14,6 +14,6 @@ var_dump($f, intl_get_error_message()); ?> --EXPECT-- NULL -string(67) "datefmt_create: invalid date format style: U_ILLEGAL_ARGUMENT_ERROR" +string(69) "datefmt_create(): invalid date format style: U_ILLEGAL_ARGUMENT_ERROR" NULL -string(67) "datefmt_create: invalid time format style: U_ILLEGAL_ARGUMENT_ERROR" +string(69) "datefmt_create(): invalid time format style: U_ILLEGAL_ARGUMENT_ERROR" diff --git a/ext/intl/tests/dateformat_calendars_variant3.phpt b/ext/intl/tests/dateformat_calendars_variant.phpt similarity index 60% rename from ext/intl/tests/dateformat_calendars_variant3.phpt rename to ext/intl/tests/dateformat_calendars_variant.phpt index 037d8066a08..48c44c58834 100644 --- a/ext/intl/tests/dateformat_calendars_variant3.phpt +++ b/ext/intl/tests/dateformat_calendars_variant.phpt @@ -8,7 +8,6 @@ intl = 0) die('skip for ICU < 72.1'); ?> --FILE-- format(strtotime('2012-01-01 00:00:00 +0000'))); var_dump($fmt2->format(strtotime('2012-01-01 00:00:00 +0000'))); var_dump($fmt3->format(strtotime('2012-01-01 00:00:00 +0000'))); -new IntlDateFormatter('en_US@calendar=hebrew', - IntlDateFormatter::FULL, - IntlDateFormatter::FULL, - 'GMT+05:12', - -1); ?> -==DONE== ---EXPECTF-- +--EXPECT-- string(47) "Sunday, January 1, 2012 at 5:12:00 AM GMT+05:12" string(47) "Sunday, January 1, 2012 at 5:12:00 AM GMT+05:12" string(44) "Sunday, 6 Tevet 5772 at 5:12:00 AM GMT+05:12" - -Fatal error: Uncaught IntlException: IntlDateFormatter::__construct(): datefmt_create: Invalid value for calendar type; it must be one of IntlDateFormatter::TRADITIONAL (locale's default calendar) or IntlDateFormatter::GREGORIAN. Alternatively, it can be an IntlCalendar object in %sdateformat_calendars_variant3.php:%d -Stack trace: -#0 %sdateformat_calendars_variant3.php(%d): IntlDateFormatter->__construct('en_US@calendar=...', 0, 0, 'GMT+05:12', -1) -#1 {main} - thrown %sdateformat_calendars_variant3.php on line %d diff --git a/ext/intl/tests/dateformat_calendars_variant_icu72-1.phpt b/ext/intl/tests/dateformat_calendars_variant_icu72-1.phpt index c63b302d8e5..d5d0f437d9b 100644 --- a/ext/intl/tests/dateformat_calendars_variant_icu72-1.phpt +++ b/ext/intl/tests/dateformat_calendars_variant_icu72-1.phpt @@ -8,7 +8,6 @@ intl = 72.1'); ?> --FILE-- format(strtotime('2012-01-01 00:00:00 +0000'))); var_dump($fmt2->format(strtotime('2012-01-01 00:00:00 +0000'))); var_dump($fmt3->format(strtotime('2012-01-01 00:00:00 +0000'))); -new IntlDateFormatter('en_US@calendar=hebrew', - IntlDateFormatter::FULL, - IntlDateFormatter::FULL, - 'GMT+05:12', - -1); ?> -==DONE== ---EXPECTF-- +--EXPECT-- string(49) "Sunday, January 1, 2012 at 5:12:00 AM GMT+05:12" string(49) "Sunday, January 1, 2012 at 5:12:00 AM GMT+05:12" string(46) "Sunday, 6 Tevet 5772 at 5:12:00 AM GMT+05:12" - -Fatal error: Uncaught IntlException: IntlDateFormatter::__construct(): datefmt_create: Invalid value for calendar type; it must be one of IntlDateFormatter::TRADITIONAL (locale's default calendar) or IntlDateFormatter::GREGORIAN. Alternatively, it can be an IntlCalendar object in %s:%d -Stack trace: -#0 %s(%d): IntlDateFormatter->__construct('en_US@calendar=...', 0, 0, 'GMT+05:12', -1) -#1 {main} - thrown in %s on line %d diff --git a/ext/intl/tests/dateformat_create_cal_arg_variant4.phpt b/ext/intl/tests/dateformat_create_cal_arg_variant4.phpt index 1571e08740e..ad09a60327d 100644 --- a/ext/intl/tests/dateformat_create_cal_arg_variant4.phpt +++ b/ext/intl/tests/dateformat_create_cal_arg_variant4.phpt @@ -2,13 +2,13 @@ IntlDateFormatter: several forms of the calendar arg --EXTENSIONS-- intl +--INI-- +intl.default_locale=pt_PT +date.timezone=Atlantic/Azores --SKIPIF-- = 0) die('skip for ICU < 58.1'); ?> --FILE-- = 58.1'); ?> --FILE-- getMessage(), PHP_EOL; +} + +$df = IntlDateFormatter::create($locale, $type, $type, $timezone, $invalidCalendar); +var_dump($df); +var_dump(intl_get_error_message()); + +$df = datefmt_create($locale, $type, $type, $timezone, $invalidCalendar); +var_dump($df); +var_dump(intl_get_error_message()); + +?> +--EXPECT-- +IntlException: IntlDateFormatter::__construct(): Invalid value for calendar type; it must be one of IntlDateFormatter::TRADITIONAL (locale's default calendar) or IntlDateFormatter::GREGORIAN. Alternatively, it can be an IntlCalendar object +NULL +string(245) "IntlDateFormatter::create(): Invalid value for calendar type; it must be one of IntlDateFormatter::TRADITIONAL (locale's default calendar) or IntlDateFormatter::GREGORIAN. Alternatively, it can be an IntlCalendar object: U_ILLEGAL_ARGUMENT_ERROR" +NULL +string(234) "datefmt_create(): Invalid value for calendar type; it must be one of IntlDateFormatter::TRADITIONAL (locale's default calendar) or IntlDateFormatter::GREGORIAN. Alternatively, it can be an IntlCalendar object: U_ILLEGAL_ARGUMENT_ERROR" diff --git a/ext/intl/tests/dateformat_formatObject_calendar_variant5.phpt b/ext/intl/tests/dateformat_formatObject_calendar_variant5.phpt index 096d04bbb51..d9a506a1dc4 100644 --- a/ext/intl/tests/dateformat_formatObject_calendar_variant5.phpt +++ b/ext/intl/tests/dateformat_formatObject_calendar_variant5.phpt @@ -2,13 +2,13 @@ IntlDateFormatter::formatObject(): IntlCalendar tests --EXTENSIONS-- intl +--INI-- +intl.default_locale=pt_PT +date.timezone=Europe/Lisbon --SKIPIF-- = 0) die('skip for ICU < 72.1'); ?> --FILE-- = 72.1'); ?> --FILE-- = 0) die('skip for ICU < 72.1'); ?> --FILE-- = 72.1'); ?> --FILE-- getMessage(), "\n"; -} $cal = IntlCalendar::createInstance(); + +try { + var_dump(IntlDateFormatter::formatObject(new B)); + var_dump(intl_get_error_message()); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; +} + +var_dump(IntlDateFormatter::formatObject(new stdclass)); +var_dump(intl_get_error_message()); +var_dump(IntlDateFormatter::formatObject(new A)); +var_dump(intl_get_error_message()); + var_dump(IntlDateFormatter::formatObject($cal, -2)); +var_dump(intl_get_error_message()); var_dump(IntlDateFormatter::formatObject($cal, array())); +var_dump(intl_get_error_message()); var_dump(IntlDateFormatter::formatObject($cal, array(1,2,3))); +var_dump(intl_get_error_message()); var_dump(IntlDateFormatter::formatObject($cal, array(array(), 1))); +var_dump(intl_get_error_message()); var_dump(IntlDateFormatter::formatObject($cal, array(1, -2))); +var_dump(intl_get_error_message()); var_dump(IntlDateFormatter::formatObject($cal, "")); +var_dump(intl_get_error_message()); ?> ---EXPECTF-- -Warning: IntlDateFormatter::formatObject(): datefmt_format_object: the passed object must be an instance of either IntlCalendar or DateTimeInterface in %s on line %d +--EXPECT-- +DateObjectError: Object of type B (inheriting DateTime) has not been correctly initialized by calling parent::__construct() in its constructor bool(false) - -Warning: IntlDateFormatter::formatObject(): datefmt_format_object: bad IntlCalendar instance: not initialized properly in %s on line %d +string(130) "IntlDateFormatter::formatObject(): the passed object must be an instance of either IntlCalendar or DateTimeInterface: U_ZERO_ERROR" bool(false) -Object of type B (inheriting DateTime) has not been correctly initialized by calling parent::__construct() in its constructor - -Warning: IntlDateFormatter::formatObject(): datefmt_format_object: the date/time format type is invalid in %s on line %d +string(112) "IntlDateFormatter::formatObject(): bad IntlCalendar instance: not initialized properly: U_ILLEGAL_ARGUMENT_ERROR" bool(false) - -Warning: IntlDateFormatter::formatObject(): datefmt_format_object: bad format; if array, it must have two elements in %s on line %d +string(97) "IntlDateFormatter::formatObject(): the date/time format type is invalid: U_ILLEGAL_ARGUMENT_ERROR" bool(false) - -Warning: IntlDateFormatter::formatObject(): datefmt_format_object: bad format; if array, it must have two elements in %s on line %d +string(108) "IntlDateFormatter::formatObject(): bad format; if array, it must have two elements: U_ILLEGAL_ARGUMENT_ERROR" bool(false) - -Warning: IntlDateFormatter::formatObject(): datefmt_format_object: bad format; the date format (first element of the array) is not valid in %s on line %d +string(108) "IntlDateFormatter::formatObject(): bad format; if array, it must have two elements: U_ILLEGAL_ARGUMENT_ERROR" bool(false) - -Warning: IntlDateFormatter::formatObject(): datefmt_format_object: bad format; the time format (second element of the array) is not valid in %s on line %d +string(130) "IntlDateFormatter::formatObject(): bad format; the date format (first element of the array) is not valid: U_ILLEGAL_ARGUMENT_ERROR" bool(false) - -Warning: IntlDateFormatter::formatObject(): datefmt_format_object: the format is empty in %s on line %d +string(131) "IntlDateFormatter::formatObject(): bad format; the time format (second element of the array) is not valid: U_ILLEGAL_ARGUMENT_ERROR" bool(false) +string(80) "IntlDateFormatter::formatObject(): the format is empty: U_ILLEGAL_ARGUMENT_ERROR" diff --git a/ext/intl/tests/dateformat_format_error.phpt b/ext/intl/tests/dateformat_format_error.phpt new file mode 100644 index 00000000000..4358271efd0 --- /dev/null +++ b/ext/intl/tests/dateformat_format_error.phpt @@ -0,0 +1,26 @@ +--TEST-- +IntlDateFormatter->format() errors +--EXTENSIONS-- +intl +--FILE-- +format($object); +var_dump($v); +var_dump(intl_get_error_message()); + +$v = datefmt_format($f, $object); +var_dump($v); +var_dump(intl_get_error_message()); + +?> +--EXPECT-- +bool(false) +string(140) "IntlDateFormatter::format(): invalid object type for date/time (only IntlCalendar and DateTimeInterface permitted): U_ILLEGAL_ARGUMENT_ERROR" +bool(false) +string(129) "datefmt_format(): invalid object type for date/time (only IntlCalendar and DateTimeInterface permitted): U_ILLEGAL_ARGUMENT_ERROR" diff --git a/ext/intl/tests/dateformat_format_relative.phpt b/ext/intl/tests/dateformat_format_relative.phpt index c93c1fd4a33..6455264142a 100644 --- a/ext/intl/tests/dateformat_format_relative.phpt +++ b/ext/intl/tests/dateformat_format_relative.phpt @@ -2,11 +2,11 @@ datefmt_format_code() with relative formats --EXTENSIONS-- intl +--INI +date.timezone=America/Los_Angeles --FILE-- setTimezone(new DateTimeZone("PDT")); - $dates = array( - $d1, - $d2, - new StdClass(), - ); //Test format with input as a timestamp : integer foreach( $time_arr as $timestamp_entry){ $res_str .= "\n------------\n"; $res_str .= "\nInput timestamp is : $timestamp_entry"; $res_str .= "\n------------\n"; - foreach( $locale_arr as $locale_entry ){ - foreach( $datetype_arr as $datetype_entry ) + foreach( $datetype_arr as $datetype_entry ) { $res_str .= "\nIntlDateFormatter locale= $locale_entry ,datetype = $datetype_entry ,timetype =$datetype_entry "; $fmt = ut_datefmt_create( $locale_entry , $datetype_entry ,$datetype_entry, $timezone, IntlDateFormatter::GREGORIAN); @@ -98,19 +88,17 @@ function ut_main() $res_str .= "\nFormatted timestamp is : $formatted"; } } - } //Test format with input as a localtime :array foreach( $localtime_arr as $localtime_entry){ $res_str .= "\n------------\n"; $res_str .= "\nInput localtime is : "; foreach( $localtime_entry as $key => $value){ - $res_str .= "$key : '$value' , "; + $res_str .= "$key : '$value' , "; } $res_str .= "\n------------\n"; - foreach( $locale_arr as $locale_entry ){ - foreach( $datetype_arr as $datetype_entry ) + foreach( $datetype_arr as $datetype_entry ) { $res_str .= "\nIntlDateFormatter locale= $locale_entry ,datetype = $datetype_entry ,timetype =$datetype_entry "; $fmt = ut_datefmt_create( $locale_entry , $datetype_entry ,$datetype_entry, $timezone, IntlDateFormatter::GREGORIAN ); @@ -122,22 +110,23 @@ function ut_main() } } } - } + $dates = array( + $d1, + $d2, + ); foreach($dates as $date_entry) { - foreach( $locale_arr as $locale_entry ){ - foreach( $datetype_arr as $datetype_entry ) { - $res_str .= "\n------------"; - $res_str .= "\nDate is: ".var_export($date_entry, true); - $res_str .= "\n------------"; + foreach( $datetype_arr as $datetype_entry ) { + $res_str .= "\n------------"; + $res_str .= "\nDate is: ".var_export($date_entry, true); + $res_str .= "\n------------"; - $fmt = ut_datefmt_create( $locale_entry , $datetype_entry ,$datetype_entry, $timezone, IntlDateFormatter::GREGORIAN ); - $formatted1 = ut_datefmt_format( $fmt , $date_entry); - if( intl_get_error_code() == U_ZERO_ERROR){ - $res_str .= "\nFormatted DateTime is : $formatted1"; - }else{ - $res_str .= "\nError while formatting as: '".intl_get_error_message()."'"; - } + $fmt = ut_datefmt_create( $locale_entry , $datetype_entry ,$datetype_entry, $timezone, IntlDateFormatter::GREGORIAN ); + $formatted1 = ut_datefmt_format( $fmt , $date_entry); + if( intl_get_error_code() == U_ZERO_ERROR){ + $res_str .= "\nFormatted DateTime is : $formatted1"; + }else{ + $res_str .= "\nError while formatting as: '".intl_get_error_message()."'"; } } } @@ -397,28 +386,3 @@ Date is: \DateTime::__set_state(array( )) ------------ Formatted DateTime is : 20001230 05:04 PM ------------- -Date is: (object) array( -) ------------- -Error while formatting as: 'datefmt_format: invalid object type for date/time (only IntlCalendar and DateTimeInterface permitted): U_ILLEGAL_ARGUMENT_ERROR' ------------- -Date is: (object) array( -) ------------- -Error while formatting as: 'datefmt_format: invalid object type for date/time (only IntlCalendar and DateTimeInterface permitted): U_ILLEGAL_ARGUMENT_ERROR' ------------- -Date is: (object) array( -) ------------- -Error while formatting as: 'datefmt_format: invalid object type for date/time (only IntlCalendar and DateTimeInterface permitted): U_ILLEGAL_ARGUMENT_ERROR' ------------- -Date is: (object) array( -) ------------- -Error while formatting as: 'datefmt_format: invalid object type for date/time (only IntlCalendar and DateTimeInterface permitted): U_ILLEGAL_ARGUMENT_ERROR' ------------- -Date is: (object) array( -) ------------- -Error while formatting as: 'datefmt_format: invalid object type for date/time (only IntlCalendar and DateTimeInterface permitted): U_ILLEGAL_ARGUMENT_ERROR' diff --git a/ext/intl/tests/dateformat_get_set_calendar_variant4.phpt b/ext/intl/tests/dateformat_get_set_calendar_variant4.phpt index 6842cdf1c40..4484bd4647a 100644 --- a/ext/intl/tests/dateformat_get_set_calendar_variant4.phpt +++ b/ext/intl/tests/dateformat_get_set_calendar_variant4.phpt @@ -2,13 +2,13 @@ IntlDateFormatter: setCalendar()/getCalendar()/getCalendarObject() --EXTENSIONS-- intl +--INI-- +intl.default_locale=pt_PT +date.timezone=Atlantic/Azores --SKIPIF-- = 0) die('skip for ICU < 58.1'); ?> --FILE-- = 58.1 and < 70.1 --EXTENSIONS-- intl +--INI-- +intl.default_locale=pt_PT +date.timezone=Atlantic/Azores --SKIPIF-- = 0) die('skip for ICU >= 58.1 and < 70.1'); ?> --FILE-- = 70.1 --EXTENSIONS-- intl +--INI-- +intl.default_locale=pt_PT +date.timezone=Atlantic/Azores --SKIPIF-- = 70.1'); ?> --FILE-- getMessage(); -} -?> ---EXPECTF-- -Warning: PHP Startup: Invalid date.timezone value 'Mars/Utopia_Planitia', using 'UTC' instead in %s on line %d -Wat? diff --git a/ext/intl/tests/dateformat_setTimeZone_error.phpt b/ext/intl/tests/dateformat_setTimeZone_error.phpt index b911c4b41ec..08ed8876d2f 100644 --- a/ext/intl/tests/dateformat_setTimeZone_error.phpt +++ b/ext/intl/tests/dateformat_setTimeZone_error.phpt @@ -2,27 +2,26 @@ IntlDateFormatter::setTimeZone() bad args --EXTENSIONS-- intl +--INI-- +intl.default_locale=pt_PT +date.timezone=Atlantic/Azores --FILE-- setTimeZone(array()); -} catch (IntlException $e) { - echo $e->getMessage() . PHP_EOL; +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; } try { $df->setTimeZone('non existing timezone'); -} catch (IntlException $e) { - echo $e->getMessage(); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; } ?> ---EXPECTF-- -Warning: Array to string conversion in %s on line %d -datefmt_set_timezone: No such time zone: 'Array' -datefmt_set_timezone: No such time zone: 'non existing timezone' +--EXPECT-- +TypeError: IntlDateFormatter::setTimeZone(): Argument #1 ($timezone) must be of type object|string|null, array given +IntlException: IntlDateFormatter::setTimeZone(): No such time zone: "non existing timezone" diff --git a/ext/intl/tests/dateformat_set_timezone_id3.phpt b/ext/intl/tests/dateformat_set_timezone_id3.phpt index 16c0bb05b9b..89e834aacdb 100644 --- a/ext/intl/tests/dateformat_set_timezone_id3.phpt +++ b/ext/intl/tests/dateformat_set_timezone_id3.phpt @@ -9,8 +9,6 @@ intl --FILE-- true, 'America/Los_Angeles' => true, 'America/Chicago' => true, - 'CN' => false ); $timestamp_entry = 0; @@ -61,10 +58,7 @@ include_once( 'ut_common.inc' ); // Run the test ut_run(); ?> ---EXPECTF-- -datefmt_set_timezone: No such time zone: 'CN' -datefmt_set_timezone: No such time zone: 'CN' - +--EXPECT-- After creation of the dateformatter : timezone_id= US/Pacific ----------- Trying to set timezone_id= America/New_York @@ -81,8 +75,3 @@ Trying to set timezone_id= America/Chicago After call to set_timezone_id : timezone_id= America/Chicago Formatting timestamp=0 resulted in Wednesday, December 31, 1969 at 6:00:00 PM Central Standard Time Formatting timestamp=3600 resulted in Wednesday, December 31, 1969 at 7:00:00 PM Central Standard Time ------------ -Trying to set timezone_id= CN -After call to set_timezone_id : timezone_id= America/Chicago -Formatting timestamp=0 resulted in Wednesday, December 31, 1969 at 6:00:00 PM Central Standard Time -Formatting timestamp=3600 resulted in Wednesday, December 31, 1969 at 7:00:00 PM Central Standard Time diff --git a/ext/intl/tests/dateformat_set_timezone_id_icu72-1.phpt b/ext/intl/tests/dateformat_set_timezone_id_icu72-1.phpt index eebc6f0973a..6424ba1e6b4 100644 --- a/ext/intl/tests/dateformat_set_timezone_id_icu72-1.phpt +++ b/ext/intl/tests/dateformat_set_timezone_id_icu72-1.phpt @@ -1,5 +1,5 @@ --TEST-- -datefmt_set_timezone_id_code() icu >= 4.8 +datefmt_set_timezone_id_code() icu >= 72.1 --INI-- date.timezone=Atlantic/Azores --EXTENSIONS-- @@ -9,8 +9,6 @@ intl --FILE-- true, 'America/Los_Angeles' => true, 'America/Chicago' => true, - 'CN' => false ); $timestamp_entry = 0; @@ -61,10 +58,7 @@ include_once( 'ut_common.inc' ); // Run the test ut_run(); ?> ---EXPECTF-- -datefmt_set_timezone: No such time zone: 'CN' -datefmt_set_timezone: No such time zone: 'CN' - +--EXPECT-- After creation of the dateformatter : timezone_id= US/Pacific ----------- Trying to set timezone_id= America/New_York @@ -81,8 +75,3 @@ Trying to set timezone_id= America/Chicago After call to set_timezone_id : timezone_id= America/Chicago Formatting timestamp=0 resulted in Wednesday, December 31, 1969 at 6:00:00 PM Central Standard Time Formatting timestamp=3600 resulted in Wednesday, December 31, 1969 at 7:00:00 PM Central Standard Time ------------ -Trying to set timezone_id= CN -After call to set_timezone_id : timezone_id= America/Chicago -Formatting timestamp=0 resulted in Wednesday, December 31, 1969 at 6:00:00 PM Central Standard Time -Formatting timestamp=3600 resulted in Wednesday, December 31, 1969 at 7:00:00 PM Central Standard Time diff --git a/ext/intl/tests/dateformat_timezone_arg_variations4.phpt b/ext/intl/tests/dateformat_timezone_arg_variations4.phpt index 0c2ea02a56d..2abdc34a2ac 100644 --- a/ext/intl/tests/dateformat_timezone_arg_variations4.phpt +++ b/ext/intl/tests/dateformat_timezone_arg_variations4.phpt @@ -2,10 +2,10 @@ IntlDateFormatter: several forms of the timezone arg --EXTENSIONS-- intl +--INI-- +date.timezone=Atlantic/Azores --FILE-- getBestPattern("YYYYMMMddjjmm"), "\n"; diff --git a/ext/intl/tests/datepatterngenerator_error.phpt b/ext/intl/tests/datepatterngenerator_error.phpt index 93419899482..6ff0e19263f 100644 --- a/ext/intl/tests/datepatterngenerator_error.phpt +++ b/ext/intl/tests/datepatterngenerator_error.phpt @@ -4,12 +4,12 @@ IntlDatePatternGenerator::getBestPattern(): errors intl --FILE-- getBestPattern("jjmm\x80")); +var_dump(intl_get_error_message()); ?> ---EXPECTF-- -Warning: IntlDatePatternGenerator::getBestPattern(): Skeleton is not a valid UTF-8 string in %s on line %d +--EXPECT-- bool(false) +string(102) "IntlDatePatternGenerator::getBestPattern(): Skeleton is not a valid UTF-8 string: U_INVALID_CHAR_FOUND" diff --git a/ext/intl/tests/datepatterngenerator_get_best_pattern.phpt b/ext/intl/tests/datepatterngenerator_get_best_pattern.phpt index 279554123b7..e67c1be2f1b 100644 --- a/ext/intl/tests/datepatterngenerator_get_best_pattern.phpt +++ b/ext/intl/tests/datepatterngenerator_get_best_pattern.phpt @@ -2,14 +2,13 @@ IntlDatePatternGenerator::getBestPattern() --EXTENSIONS-- intl +--INI-- +intl.default_locale=en_US --SKIPIF-- = 0) die('skip for ICU < 72.1'); ?> --FILE-- getBestPattern("YYYYMMMdd"), "\n"; echo $dtpg->getBestPattern(""), "\n"; -try { - $dtpg->getBestPattern(); -} catch(\ArgumentCountError $e) { - echo $e->getMessage(), "\n"; -} - ?> --EXPECT-- h:mm a HH:mm MMM dd, YYYY dd. MMM YYYY - -IntlDatePatternGenerator::getBestPattern() expects exactly 1 argument, 0 given diff --git a/ext/intl/tests/datepatterngenerator_get_best_pattern_icu72-1.phpt b/ext/intl/tests/datepatterngenerator_get_best_pattern_icu72-1.phpt index 2f4f744757c..c35b2ff8d48 100644 --- a/ext/intl/tests/datepatterngenerator_get_best_pattern_icu72-1.phpt +++ b/ext/intl/tests/datepatterngenerator_get_best_pattern_icu72-1.phpt @@ -2,14 +2,13 @@ IntlDatePatternGenerator::getBestPattern() --EXTENSIONS-- intl +--INI-- +intl.default_locale=en_US --SKIPIF-- = 72.1'); ?> --FILE-- getBestPattern("YYYYMMMdd"), "\n"; echo $dtpg->getBestPattern(""), "\n"; -try { - $dtpg->getBestPattern(); -} catch(\ArgumentCountError $e) { - echo $e->getMessage(), "\n"; -} - ?> --EXPECT-- h:mm a HH:mm MMM dd, YYYY dd. MMM YYYY - -IntlDatePatternGenerator::getBestPattern() expects exactly 1 argument, 0 given diff --git a/ext/intl/tests/formatter/rounding_modes.phpt b/ext/intl/tests/formatter/rounding_modes.phpt index 3261e374079..bcb32983959 100644 --- a/ext/intl/tests/formatter/rounding_modes.phpt +++ b/ext/intl/tests/formatter/rounding_modes.phpt @@ -6,7 +6,6 @@ intl = 69.0'); ?> --FILE-- getMessage() - . " in " . $e->getFile() . " on line " . $e->getLine() . "\n"; + echo "\n", $e::class, ": ", $e->getMessage(), "\n"; } function crt($t, $l, $s) { @@ -62,14 +61,14 @@ try { err($fmt); try { $fmt = numfmt_create(); -} catch (TypeError $e) { +} catch (Throwable $e) { print_exception($e); $fmt = null; } err($fmt); try { $fmt = NumberFormatter::create(); -} catch (TypeError $e) { +} catch (Throwable $e) { print_exception($e); $fmt = null; } @@ -78,7 +77,7 @@ err($fmt); $fmt = new NumberFormatter('en_US', NumberFormatter::DECIMAL); try { $fmt->__construct('en_US', NumberFormatter::DECIMAL); -} catch (Error $e) { +} catch (Throwable $e) { print_exception($e); $fmt = null; } @@ -95,16 +94,16 @@ foreach($args as $arg) { ?> --EXPECTF-- -ArgumentCountError: NumberFormatter::__construct() expects at least 2 arguments, 0 given in %s on line %d +ArgumentCountError: NumberFormatter::__construct() expects at least 2 arguments, 0 given 'U_ZERO_ERROR' -ArgumentCountError: numfmt_create() expects at least 2 arguments, 0 given in %s on line %d +ArgumentCountError: numfmt_create() expects at least 2 arguments, 0 given 'U_ZERO_ERROR' -ArgumentCountError: NumberFormatter::create() expects at least 2 arguments, 0 given in %s on line %d +ArgumentCountError: NumberFormatter::create() expects at least 2 arguments, 0 given 'U_ZERO_ERROR' -Error: NumberFormatter object is already constructed in %s on line %d +Error: NumberFormatter object is already constructed 'U_ZERO_ERROR' Deprecated: NumberFormatter::__construct(): Passing null to parameter #1 ($locale) of type string is deprecated in %s on line %d @@ -119,30 +118,30 @@ Deprecated: numfmt_create(): Passing null to parameter #1 ($locale) of type stri Deprecated: numfmt_create(): Passing null to parameter #2 ($style) of type int is deprecated in %s on line %d -ValueError: NumberFormatter::__construct(): Argument #1 ($locale) "%s" is invalid in %s on line %d +ValueError: NumberFormatter::__construct(): Argument #1 ($locale) "whatever" is invalid 'U_ZERO_ERROR' -ValueError: NumberFormatter::create(): Argument #1 ($locale) "%s" is invalid in %s on line %d +ValueError: NumberFormatter::create(): Argument #1 ($locale) "whatever" is invalid 'U_ZERO_ERROR' -ValueError: numfmt_create(): Argument #1 ($locale) "%s" is invalid in %s on line %d +ValueError: numfmt_create(): Argument #1 ($locale) "whatever" is invalid 'U_ZERO_ERROR' -TypeError: NumberFormatter::__construct(): Argument #1 ($locale) must be of type string, array given in %s on line %d +TypeError: NumberFormatter::__construct(): Argument #1 ($locale) must be of type string, array given 'U_ZERO_ERROR' -TypeError: NumberFormatter::create(): Argument #1 ($locale) must be of type string, array given in %s on line %d +TypeError: NumberFormatter::create(): Argument #1 ($locale) must be of type string, array given 'U_ZERO_ERROR' -TypeError: numfmt_create(): Argument #1 ($locale) must be of type string, array given in %s on line %d +TypeError: numfmt_create(): Argument #1 ($locale) must be of type string, array given 'U_ZERO_ERROR' -IntlException: Constructor failed in %s on line %d -'numfmt_create: number formatter creation failed: U_UNSUPPORTED_ERROR' -'numfmt_create: number formatter creation failed: U_UNSUPPORTED_ERROR' -'numfmt_create: number formatter creation failed: U_UNSUPPORTED_ERROR' +IntlException: NumberFormatter::__construct(): number formatter creation failed +'NumberFormatter::__construct(): number formatter creation failed: U_UNSUPPORTED_ERROR' +'NumberFormatter::create(): number formatter creation failed: U_UNSUPPORTED_ERROR' +'numfmt_create(): number formatter creation failed: U_UNSUPPORTED_ERROR' -IntlException: Constructor failed in %s on line %d -'numfmt_create: number formatter creation failed: U_MEMORY_ALLOCATION_ERROR' -'numfmt_create: number formatter creation failed: U_MEMORY_ALLOCATION_ERROR' -'numfmt_create: number formatter creation failed: U_MEMORY_ALLOCATION_ERROR' +IntlException: NumberFormatter::__construct(): number formatter creation failed +'NumberFormatter::__construct(): number formatter creation failed: U_MEMORY_ALLOCATION_ERROR' +'NumberFormatter::create(): number formatter creation failed: U_MEMORY_ALLOCATION_ERROR' +'numfmt_create(): number formatter creation failed: U_MEMORY_ALLOCATION_ERROR' diff --git a/ext/intl/tests/formatter_get_error.phpt b/ext/intl/tests/formatter_get_error.phpt index b8f1269fc65..16a1c1db476 100644 --- a/ext/intl/tests/formatter_get_error.phpt +++ b/ext/intl/tests/formatter_get_error.phpt @@ -5,27 +5,43 @@ intl --FILE-- parseCurrency('123.45', $currency); +var_dump($currency); +var_dump($nf->getErrorMessage()); +var_dump($nf->getErrorCode()); +$pos = 0; +$nf->parseCurrency('123.45', $currency, $pos); +var_dump($currency); +var_dump($nf->getErrorMessage()); +var_dump($nf->getErrorCode()); -function ut_main() -{ - $fmt = ut_nfmt_create( "en_US", NumberFormatter::CURRENCY ); - $currency = ''; - $pos = 0; - $num = ut_nfmt_parse_currency( $fmt, '123.45', $currency, $pos ); - if( $num === false ) - return $fmt->getErrorMessage() . " (" . $fmt->getErrorCode() . ")\n"; - else - return "Ooops, an error should have occurred."; -} +$nf = numfmt_create("en_US", NumberFormatter::CURRENCY); +var_dump(numfmt_parse_currency($nf, '123.45', $currency)); +var_dump($currency); +var_dump($nf->getErrorMessage()); +var_dump($nf->getErrorCode()); -include_once( 'ut_common.inc' ); +$pos = 0; +var_dump(numfmt_parse_currency($nf, '123.45', $currency, $pos)); +var_dump($currency); +var_dump($nf->getErrorMessage()); +var_dump($nf->getErrorCode()); -// Run the test -ut_run(); ?> --EXPECT-- -Number parsing failed: U_PARSE_ERROR (9) +NULL +string(70) "NumberFormatter::parseCurrency(): Number parsing failed: U_PARSE_ERROR" +int(9) +NULL +string(70) "NumberFormatter::parseCurrency(): Number parsing failed: U_PARSE_ERROR" +int(9) +bool(false) +NULL +string(61) "numfmt_parse_currency(): Number parsing failed: U_PARSE_ERROR" +int(9) +bool(false) +NULL +string(61) "numfmt_parse_currency(): Number parsing failed: U_PARSE_ERROR" +int(9) diff --git a/ext/intl/tests/formatter_get_set_pattern2.phpt b/ext/intl/tests/formatter_get_set_pattern2.phpt index 0d3e3e87d72..7b454ae965e 100644 --- a/ext/intl/tests/formatter_get_set_pattern2.phpt +++ b/ext/intl/tests/formatter_get_set_pattern2.phpt @@ -37,10 +37,6 @@ function ut_main() ut_nfmt_set_pattern($fmt, str_repeat('@', 200)); $res_str .= "New pattern: '" . ut_nfmt_get_pattern( $fmt ) . "'\n"; $res_str .= "Formatted number: " . ut_nfmt_format( $fmt, $test_value ) . "\n"; - $res = ut_nfmt_set_pattern( $fmt, "0.0 .#.#.#"); - if ($res !== false) - die("ut_nfmt_set_pattern should have failed"); - $res_str .= ut_nfmt_get_error_message( $fmt ) . " (" . ut_nfmt_get_error_code( $fmt ) . ")\n"; return $res_str; } @@ -56,4 +52,3 @@ New pattern: '0.0' Formatted number: 12345.1 New pattern: '@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@' Formatted number: 12345.123456000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 -Error setting pattern value at line 0, offset 0: U_UNQUOTED_SPECIAL (65555) diff --git a/ext/intl/tests/formatter_set_invalid_pattern.phpt b/ext/intl/tests/formatter_set_invalid_pattern.phpt new file mode 100644 index 00000000000..2e94719e756 --- /dev/null +++ b/ext/intl/tests/formatter_set_invalid_pattern.phpt @@ -0,0 +1,21 @@ +--TEST-- +numfmt_set_pattern() with invalid pattern +--EXTENSIONS-- +intl +--FILE-- +setPattern($pattern)); +var_dump($fmt->getErrorMessage()); +var_dump(numfmt_set_pattern($fmt, $pattern)); +var_dump(numfmt_get_error_message($fmt)); + +?> +--EXPECT-- +bool(false) +string(98) "NumberFormatter::setPattern(): Error setting pattern value at line 0, offset 0: U_UNQUOTED_SPECIAL" +bool(false) +string(89) "numfmt_set_pattern(): Error setting pattern value at line 0, offset 0: U_UNQUOTED_SPECIAL" diff --git a/ext/intl/tests/gh11658.phpt b/ext/intl/tests/gh11658.phpt index f0cfab9280e..da3cc8b9a1c 100644 --- a/ext/intl/tests/gh11658.phpt +++ b/ext/intl/tests/gh11658.phpt @@ -5,17 +5,17 @@ intl --FILE-- ---EXPECTF-- -Warning: MessageFormatter::formatMessage(): pattern syntax error (parse error at offset 6, after "some {", before or at "wrong.format}") in %s on line %d -bool(false) +echo intl_get_error_message(), PHP_EOL; -Warning: msgfmt_format_message(): pattern syntax error (parse error at offset 6, after "some {", before or at "wrong.format}") in %s on line %d +?> +--EXPECT-- bool(false) +MessageFormatter::formatMessage(): pattern syntax error (parse error at offset 6, after "some {", before or at "wrong.format}"): U_PATTERN_SYNTAX_ERROR +bool(false) +msgfmt_format_message(): pattern syntax error (parse error at offset 6, after "some {", before or at "wrong.format}"): U_PATTERN_SYNTAX_ERROR diff --git a/ext/intl/tests/gh12020.phpt b/ext/intl/tests/gh12020.phpt index e4102606ca5..c9fe55fa3cd 100644 --- a/ext/intl/tests/gh12020.phpt +++ b/ext/intl/tests/gh12020.phpt @@ -13,10 +13,10 @@ var_dump(msgfmt_format_message('en', 'some {wrong.format}', []), intl_get_error_ ?> --EXPECT-- bool(false) -string(128) "pattern syntax error (parse error at offset 19, after " message with {", before or at "invalid format}"): U_PATTERN_SYNTAX_ERROR" +string(163) "MessageFormatter::formatMessage(): pattern syntax error (parse error at offset 19, after " message with {", before or at "invalid format}"): U_PATTERN_SYNTAX_ERROR" bool(false) -string(116) "pattern syntax error (parse error at offset 6, after "some {", before or at "wrong.format}"): U_PATTERN_SYNTAX_ERROR" +string(151) "MessageFormatter::formatMessage(): pattern syntax error (parse error at offset 6, after "some {", before or at "wrong.format}"): U_PATTERN_SYNTAX_ERROR" bool(false) -string(128) "pattern syntax error (parse error at offset 19, after " message with {", before or at "invalid format}"): U_PATTERN_SYNTAX_ERROR" +string(153) "msgfmt_format_message(): pattern syntax error (parse error at offset 19, after " message with {", before or at "invalid format}"): U_PATTERN_SYNTAX_ERROR" bool(false) -string(116) "pattern syntax error (parse error at offset 6, after "some {", before or at "wrong.format}"): U_PATTERN_SYNTAX_ERROR" +string(141) "msgfmt_format_message(): pattern syntax error (parse error at offset 6, after "some {", before or at "wrong.format}"): U_PATTERN_SYNTAX_ERROR" diff --git a/ext/intl/tests/gh12243.phpt b/ext/intl/tests/gh12243.phpt index cb2b1776039..786a9bd1ee8 100644 --- a/ext/intl/tests/gh12243.phpt +++ b/ext/intl/tests/gh12243.phpt @@ -21,4 +21,4 @@ try { ?> --EXPECT-- -datefmt_create: time format must be UDAT_PATTERN if date format is UDAT_PATTERN: U_ILLEGAL_ARGUMENT_ERROR +IntlDateFormatter::__construct(): time format must be UDAT_PATTERN if date format is UDAT_PATTERN diff --git a/ext/intl/tests/gh17469.phpt b/ext/intl/tests/gh17469.phpt index a0c5d719817..5a226368442 100644 --- a/ext/intl/tests/gh17469.phpt +++ b/ext/intl/tests/gh17469.phpt @@ -1,5 +1,7 @@ --TEST-- GH-17469: UConverter::transcode() raises always E_WARNING regardless of INI settings +--EXTENSIONS-- +intl --SKIPIF-- --EXPECTF-- +Deprecated: ini_set(): Using a value different than 0 for intl.error_level is deprecated, as the intl.error_level INI setting is deprecated. Instead the intl.use_exceptions INI setting should be enabled to throw exceptions on errors or intl_get_error_code()/intl_get_error_message() should be used to manually deal with errors in %s on line %d Warning: UConverter::transcode(): Error setting encoding: 4 - U_FILE_ACCESS_ERROR in %s on line %d -Warning: UConverter::transcode(): Error setting encoding: 4 - U_FILE_ACCESS_ERROR in %s on line 5 -Error setting encoding: 4 - U_FILE_ACCESS_ERROR -Error setting encoding: 4 - U_FILE_ACCESS_ERROR +Warning: UConverter::transcode(): Error setting encoding: 4 - U_FILE_ACCESS_ERROR in %s on line %d +UConverter::transcode(): Error setting encoding: 4 - U_FILE_ACCESS_ERROR +UConverter::transcode(): Error setting encoding: 4 - U_FILE_ACCESS_ERROR diff --git a/ext/intl/tests/grapheme_empty.phpt b/ext/intl/tests/grapheme_empty.phpt index 815663342fc..cf2f1185abf 100644 --- a/ext/intl/tests/grapheme_empty.phpt +++ b/ext/intl/tests/grapheme_empty.phpt @@ -5,8 +5,6 @@ intl --FILE-- getTimeZone()->getId()); diff --git a/ext/intl/tests/gregoriancalendar___construct_error.phpt b/ext/intl/tests/gregoriancalendar___construct_error.phpt index 2261da3955b..6922b7cadd8 100644 --- a/ext/intl/tests/gregoriancalendar___construct_error.phpt +++ b/ext/intl/tests/gregoriancalendar___construct_error.phpt @@ -4,7 +4,6 @@ IntlGregorianCalendar::__construct(): bad arguments intl --FILE-- getTimeZone()->getId()); diff --git a/ext/intl/tests/gregoriancalendar_getGregorianChange_error.phpt b/ext/intl/tests/gregoriancalendar_getGregorianChange_error.phpt deleted file mode 100644 index 5665b793f38..00000000000 --- a/ext/intl/tests/gregoriancalendar_getGregorianChange_error.phpt +++ /dev/null @@ -1,19 +0,0 @@ ---TEST-- -IntlGregorianCalendar::getGregorianChange(): bad arguments ---INI-- -date.timezone=Atlantic/Azores ---EXTENSIONS-- -intl ---FILE-- - ---EXPECTF-- -Fatal error: Uncaught TypeError: intlgregcal_get_gregorian_change(): Argument #1 ($calendar) must be of type IntlGregorianCalendar, int given in %s:%d -Stack trace: -#0 %s(%d): intlgregcal_get_gregorian_change(1) -#1 {main} - thrown in %s on line %d diff --git a/ext/intl/tests/gregoriancalendar_get_setGregorianChange_basic.phpt b/ext/intl/tests/gregoriancalendar_get_setGregorianChange_basic.phpt index 8ae2410dc8c..e0cd6b13b2e 100644 --- a/ext/intl/tests/gregoriancalendar_get_setGregorianChange_basic.phpt +++ b/ext/intl/tests/gregoriancalendar_get_setGregorianChange_basic.phpt @@ -2,12 +2,11 @@ IntlGregorianCalendar::get/setGregorianChange(): basic test --EXTENSIONS-- intl +--INI-- +date.timezone=Europe/Amsterdam +intl.default_locale=nl --FILE-- ---EXPECTF-- -Fatal error: Uncaught TypeError: intlgregcal_is_leap_year(): Argument #1 ($calendar) must be of type IntlGregorianCalendar, int given in %s:%d -Stack trace: -#0 %s(%d): intlgregcal_is_leap_year(1, 2) -#1 {main} - thrown in %s on line %d diff --git a/ext/intl/tests/idn_uts46_errors.phpt b/ext/intl/tests/idn_uts46_errors.phpt index 1cbf336defa..c1058c3a243 100644 --- a/ext/intl/tests/idn_uts46_errors.phpt +++ b/ext/intl/tests/idn_uts46_errors.phpt @@ -9,7 +9,6 @@ intl ?> --FILE-- PHP level errors", "\n"; echo "bad variant:", "\n"; diff --git a/ext/intl/tests/ini_use_exceptions_basic.phpt b/ext/intl/tests/ini_use_exceptions_basic.phpt index c2aabfbe63f..e03c991ae05 100644 --- a/ext/intl/tests/ini_use_exceptions_basic.phpt +++ b/ext/intl/tests/ini_use_exceptions_basic.phpt @@ -16,7 +16,9 @@ ini_set("intl.error_level", E_NOTICE); var_dump($t->transliterate('a', 3)); ?> --EXPECTF-- -string(130) "transliterator_transliterate: Neither "start" nor the "end" arguments can exceed the number of UTF-16 code units (in this case, 1)" +string(133) "Transliterator::transliterate(): Neither "start" nor the "end" arguments can exceed the number of UTF-16 code units (in this case, 1)" -Notice: Transliterator::transliterate(): transliterator_transliterate: Neither "start" nor the "end" arguments can exceed the number of UTF-16 code units (in this case, 1) in %s on line %d +Deprecated: ini_set(): Using a value different than 0 for intl.error_level is deprecated, as the intl.error_level INI setting is deprecated. Instead the intl.use_exceptions INI setting should be enabled to throw exceptions on errors or intl_get_error_code()/intl_get_error_message() should be used to manually deal with errors in %s on line %d + +Notice: Transliterator::transliterate(): Neither "start" nor the "end" arguments can exceed the number of UTF-16 code units (in this case, 1) in %s on line %d bool(false) diff --git a/ext/intl/tests/intl_get_error_message.phpt b/ext/intl/tests/intl_get_error_message.phpt index 93d2e5c653a..83130e549dc 100644 --- a/ext/intl/tests/intl_get_error_message.phpt +++ b/ext/intl/tests/intl_get_error_message.phpt @@ -15,4 +15,4 @@ else ?> --EXPECT-- -Error getting locale by type: U_ILLEGAL_ARGUMENT_ERROR +collator_get_locale(): Error getting locale by type: U_ILLEGAL_ARGUMENT_ERROR diff --git a/ext/intl/tests/listformatter/listformatter_error.phpt b/ext/intl/tests/listformatter/listformatter_error.phpt index d420b92a9f8..4ca22136943 100644 --- a/ext/intl/tests/listformatter/listformatter_error.phpt +++ b/ext/intl/tests/listformatter/listformatter_error.phpt @@ -33,6 +33,6 @@ try { ?> --EXPECT-- IntlListFormatter::__construct(): Argument #1 ($locale) "f" is invalid -IntlListFormatter::__construct(): Argument #1 ($locale) Locale string too long, should be no longer than 156 characters +IntlListFormatter::__construct(): Argument #1 ($locale) must be less than or equal to 156 characters Object of class stdClass could not be converted to string Object of class stdClass could not be converted to string diff --git a/ext/intl/tests/locale_compose_locale.phpt b/ext/intl/tests/locale_compose_locale.phpt index 0a2a501b9ba..beaf4beaa8a 100644 --- a/ext/intl/tests/locale_compose_locale.phpt +++ b/ext/intl/tests/locale_compose_locale.phpt @@ -13,115 +13,89 @@ intl function ut_main() { $loc_parts_arr1 = array( - Locale::LANG_TAG =>'sl' , - Locale::SCRIPT_TAG =>'Latn' , - Locale::REGION_TAG =>'IT' + Locale::LANG_TAG => 'sl', + Locale::SCRIPT_TAG => 'Latn', + Locale::REGION_TAG => 'IT' ); $loc_parts_arr2 = array( - Locale::LANG_TAG =>'de' , - Locale::REGION_TAG =>'DE' + Locale::LANG_TAG => 'de', + Locale::REGION_TAG => 'DE' ); $loc_parts_arr3 = array( - Locale::LANG_TAG =>'hi' + Locale::LANG_TAG => 'hi' ); $loc_parts_arr4 = array( - Locale::LANG_TAG =>'zh' , - Locale::SCRIPT_TAG =>'Hans' , - Locale::REGION_TAG =>'CN' + Locale::LANG_TAG => 'zh', + Locale::SCRIPT_TAG => 'Hans', + Locale::REGION_TAG => 'CN' ); $loc_parts_arr5 = array( - Locale::LANG_TAG =>'es' , - Locale::SCRIPT_TAG =>'Hans' , - Locale::REGION_TAG =>'CN' + Locale::LANG_TAG => 'es', + Locale::SCRIPT_TAG => 'Hans', + Locale::REGION_TAG => 'CN' ); $loc_parts_arr6 = array( - Locale::LANG_TAG =>'en' , - Locale::SCRIPT_TAG =>'Hans' , - Locale::REGION_TAG =>'CN', - Locale::VARIANT_TAG.'14' =>'rozaj' , - 'variant1'=>'nedis' + Locale::LANG_TAG => 'en', + Locale::SCRIPT_TAG => 'Hans', + Locale::REGION_TAG => 'CN', + Locale::VARIANT_TAG.'14' => 'rozaj', + 'variant1' => 'nedis' ); $loc_parts_arr7 = array( - Locale::LANG_TAG =>'en' , - Locale::SCRIPT_TAG =>'Hans' , - Locale::REGION_TAG =>'CN', - 'variant14'=>'rozaj' , - 'variant1'=>'nedis' , - 'extlang0'=>'lng' , - 'extlang1'=>'ing' + Locale::LANG_TAG => 'en', + Locale::SCRIPT_TAG => 'Hans', + Locale::REGION_TAG => 'CN', + 'variant14' => 'rozaj', + 'variant1' => 'nedis', + 'extlang0' => 'lng', + 'extlang1' => 'ing' ); $loc_parts_arr8 = array( - Locale::LANG_TAG =>'en' , - Locale::SCRIPT_TAG =>'Hans' , - Locale::REGION_TAG =>'CN', - 'variant14'=>'rozaj' , - 'variant1'=>'nedis' , - 'extlang0'=>'lng' , - 'extlang1'=>'ing', - 'private7'=>'prv1' , - 'private9'=>'prv2' + Locale::LANG_TAG => 'en', + Locale::SCRIPT_TAG => 'Hans', + Locale::REGION_TAG => 'CN', + 'variant14' => 'rozaj', + 'variant1' => 'nedis', + 'extlang0' => 'lng', + 'extlang1' => 'ing', + 'private7' => 'prv1', + 'private9' => 'prv2' ); $loc_parts_arr9 = array( - Locale::REGION_TAG =>'DE' - ); - $loc_parts_arr10 = array( - Locale::LANG_TAG => 45, - Locale::REGION_TAG => false, - Locale::SCRIPT_TAG => 15 - ); - $loc_parts_arr11 = array( - Locale::LANG_TAG =>'de' , - Locale::REGION_TAG =>'DE', - 'private0' => 13, - 'variant1' => array(), - 'extlang2' => false - ); - $loc_parts_arr12 = array( - Locale::LANG_TAG =>'en' , - Locale::SCRIPT_TAG =>'Hans' , - Locale::REGION_TAG =>'CN', - Locale::VARIANT_TAG => array('nedis', 'rozaj'), + Locale::LANG_TAG => 'en', + Locale::SCRIPT_TAG => 'Hans', + Locale::REGION_TAG => 'CN', + Locale::VARIANT_TAG => array('nedis', 'rozaj'), Locale::PRIVATE_TAG => array('prv1', 'prv2'), Locale::EXTLANG_TAG => array('lng', 'ing') - ); + ); $loc_parts_arr = array( - 'loc1' => $loc_parts_arr1 , - 'loc2' => $loc_parts_arr2 , - 'loc3' => $loc_parts_arr3 , - 'loc4' => $loc_parts_arr4 , - 'loc5' => $loc_parts_arr5 , - 'loc6' => $loc_parts_arr6 , - 'loc7' => $loc_parts_arr7 , - 'loc8' => $loc_parts_arr8 , - 'loc9' => $loc_parts_arr9 , - 'loc10' => $loc_parts_arr10 , - 'loc11' => $loc_parts_arr11 , - 'loc12' => $loc_parts_arr12 + 'loc1' => $loc_parts_arr1, + 'loc2' => $loc_parts_arr2, + 'loc3' => $loc_parts_arr3, + 'loc4' => $loc_parts_arr4, + 'loc5' => $loc_parts_arr5, + 'loc6' => $loc_parts_arr6, + 'loc7' => $loc_parts_arr7, + 'loc8' => $loc_parts_arr8, + 'loc9' => $loc_parts_arr9, ); $cnt = 0; $res_str = ''; - foreach($loc_parts_arr as $key => $value ){ + foreach ($loc_parts_arr as $key => $value) { $res_str .= "\n------------"; $res_str .= "\nInput Array name is : loc".(++$cnt) ; -/* - foreach($value as $valKey => $valValue ){ - $res_str .= $valKey ."->".$valValue." " ; - } -*/ - try { - $locale = ut_loc_locale_compose( $value); - $res_str .= "\n\nComposed Locale: "; - if( $locale){ - $res_str .= "$locale"; - }else{ - $res_str .= "No values found from Locale compose due to the following error:\n"; - $res_str .= intl_get_error_message() ; - } - } catch (ValueError $exception) { - echo $exception->getMessage() . "\n"; + + $locale = ut_loc_locale_compose( $value); + $res_str .= "\n\nComposed Locale: "; + if ($locale) { + $res_str .= "$locale"; + } else { + $res_str .= "No values found from Locale compose due to the following error:\n"; + $res_str .= intl_get_error_message() ; } } @@ -136,9 +110,6 @@ ut_run(); ?> --EXPECT-- -Locale::composeLocale(): Argument #1 ($subtags) must contain a "language" key -locale_compose(): Argument #1 ($subtags) must contain a "language" key - ------------ Input Array name is : loc1 @@ -173,18 +144,6 @@ Input Array name is : loc8 Composed Locale: en_lng_ing_Hans_CN_nedis_rozaj_x_prv1_prv2 ------------ Input Array name is : loc9 ------------- -Input Array name is : loc10 - -Composed Locale: No values found from Locale compose due to the following error: -locale_compose: parameter array element is not a string: U_ILLEGAL_ARGUMENT_ERROR ------------- -Input Array name is : loc11 - -Composed Locale: No values found from Locale compose due to the following error: -locale_compose: parameter array element is not a string: U_ILLEGAL_ARGUMENT_ERROR ------------- -Input Array name is : loc12 Composed Locale: en_lng_ing_Hans_CN_nedis_rozaj_x_prv1_prv2 ------------ diff --git a/ext/intl/tests/locale_compose_locale_errors.phpt b/ext/intl/tests/locale_compose_locale_errors.phpt new file mode 100644 index 00000000000..b0d68aae73c --- /dev/null +++ b/ext/intl/tests/locale_compose_locale_errors.phpt @@ -0,0 +1,58 @@ +--TEST-- +locale_compose_locale() errors +--EXTENSIONS-- +intl +--FILE-- + 45, + Locale::REGION_TAG => false, + Locale::SCRIPT_TAG => 15, +]; + +var_dump(Locale::composeLocale($parts1)); +var_dump(intl_get_error_message()); +var_dump(locale_compose($parts1)); +var_dump(intl_get_error_message()); + +$parts2 = [ + Locale::LANG_TAG => 'de', + Locale::REGION_TAG => 'DE', + 'private0' => 13, + 'variant1' => array(), + 'extlang2' => false +]; + +var_dump(Locale::composeLocale($parts2)); +var_dump(intl_get_error_message()); +var_dump(locale_compose($parts2)); +var_dump(intl_get_error_message()); + +$parts3 = [ + Locale::REGION_TAG => 'DE', +]; + +try { + var_dump(Locale::composeLocale($parts3)); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; +} +try { + var_dump(locale_compose($parts3)); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; +} + +?> +--EXPECT-- +bool(false) +string(90) "Locale::composeLocale(): parameter array element is not a string: U_ILLEGAL_ARGUMENT_ERROR" +bool(false) +string(83) "locale_compose(): parameter array element is not a string: U_ILLEGAL_ARGUMENT_ERROR" +bool(false) +string(90) "Locale::composeLocale(): parameter array element is not a string: U_ILLEGAL_ARGUMENT_ERROR" +bool(false) +string(83) "locale_compose(): parameter array element is not a string: U_ILLEGAL_ARGUMENT_ERROR" +ValueError: Locale::composeLocale(): Argument #1 ($subtags) must contain a "language" key +ValueError: locale_compose(): Argument #1 ($subtags) must contain a "language" key diff --git a/ext/intl/tests/locale_subtags.phpt b/ext/intl/tests/locale_subtags.phpt index 0c454706225..f6cb7d1e957 100644 --- a/ext/intl/tests/locale_subtags.phpt +++ b/ext/intl/tests/locale_subtags.phpt @@ -26,10 +26,10 @@ bool(true) bool(true) bool(true) bool(false) -string(67) "locale_add_likely_subtags: invalid locale: U_ILLEGAL_ARGUMENT_ERROR" +string(68) "Locale::addLikelySubtags(): invalid locale: U_ILLEGAL_ARGUMENT_ERROR" bool(false) -string(65) "locale_minimize_subtags: invalid locale: U_ILLEGAL_ARGUMENT_ERROR" +string(67) "Locale::minimizeSubtags(): invalid locale: U_ILLEGAL_ARGUMENT_ERROR" bool(false) -string(%d) "locale_add_likely_subtags: invalid locale: %s" +string(68) "Locale::addLikelySubtags(): invalid locale: U_ILLEGAL_ARGUMENT_ERROR" bool(false) -string(%d) "locale_minimize_subtags: invalid locale: %s" +string(%d) "Locale::minimizeSubtags(): invalid locale: %s" diff --git a/ext/intl/tests/msgfmt_errors.phpt b/ext/intl/tests/msgfmt_errors.phpt new file mode 100644 index 00000000000..78264c22b3a --- /dev/null +++ b/ext/intl/tests/msgfmt_errors.phpt @@ -0,0 +1,30 @@ +--TEST-- +MessageFormatter with invalid locale +--EXTENSIONS-- +intl +--FILE-- +getMessage(), PHP_EOL; +} + +$mf = MessageFormatter::create('root', $fmt); +var_dump($mf); +var_dump(intl_get_error_message()); + +$mf = msgfmt_create('root', $fmt); +var_dump($mf); +var_dump(intl_get_error_message()); + +?> +--EXPECT-- +IntlException: MessageFormatter::__construct(): message formatter creation failed +NULL +string(87) "MessageFormatter::create(): message formatter creation failed: U_ILLEGAL_ARGUMENT_ERROR" +NULL +string(76) "msgfmt_create(): message formatter creation failed: U_ILLEGAL_ARGUMENT_ERROR" diff --git a/ext/intl/tests/msgfmt_fail2.phpt b/ext/intl/tests/msgfmt_fail2.phpt index a5256e724a0..de592e7b798 100644 --- a/ext/intl/tests/msgfmt_fail2.phpt +++ b/ext/intl/tests/msgfmt_fail2.phpt @@ -130,23 +130,23 @@ Deprecated: MessageFormatter::__construct(): Passing null to parameter #1 ($loca Deprecated: MessageFormatter::__construct(): Passing null to parameter #2 ($pattern) of type string is deprecated in %s on line %d -IntlException: msgfmt_create: message formatter creation failed: U_ILLEGAL_ARGUMENT_ERROR in %s on line %d -'msgfmt_create: message formatter creation failed: U_ILLEGAL_ARGUMENT_ERROR' +IntlException: MessageFormatter::__construct(): message formatter creation failed in %s on line %d +'MessageFormatter::__construct(): message formatter creation failed: U_ILLEGAL_ARGUMENT_ERROR' Deprecated: MessageFormatter::create(): Passing null to parameter #1 ($locale) of type string is deprecated in %s on line %d Deprecated: MessageFormatter::create(): Passing null to parameter #2 ($pattern) of type string is deprecated in %s on line %d -'msgfmt_create: message formatter creation failed: U_ILLEGAL_ARGUMENT_ERROR' +'MessageFormatter::create(): message formatter creation failed: U_ILLEGAL_ARGUMENT_ERROR' Deprecated: msgfmt_create(): Passing null to parameter #1 ($locale) of type string is deprecated in %s on line %d Deprecated: msgfmt_create(): Passing null to parameter #2 ($pattern) of type string is deprecated in %s on line %d -'msgfmt_create: message formatter creation failed: U_ILLEGAL_ARGUMENT_ERROR' +'msgfmt_create(): message formatter creation failed: U_ILLEGAL_ARGUMENT_ERROR' -IntlException: msgfmt_create: message formatter creation failed: U_ILLEGAL_ARGUMENT_ERROR in %s on line %d -'msgfmt_create: message formatter creation failed: U_ILLEGAL_ARGUMENT_ERROR' -'msgfmt_create: message formatter creation failed: U_ILLEGAL_ARGUMENT_ERROR' -'msgfmt_create: message formatter creation failed: U_ILLEGAL_ARGUMENT_ERROR' +IntlException: MessageFormatter::__construct(): message formatter creation failed in %s on line %d +'MessageFormatter::__construct(): message formatter creation failed: U_ILLEGAL_ARGUMENT_ERROR' +'MessageFormatter::create(): message formatter creation failed: U_ILLEGAL_ARGUMENT_ERROR' +'msgfmt_create(): message formatter creation failed: U_ILLEGAL_ARGUMENT_ERROR' TypeError: MessageFormatter::__construct(): Argument #1 ($locale) must be of type string, array given in %s on line %d 'U_ZERO_ERROR' @@ -157,17 +157,17 @@ TypeError: MessageFormatter::create(): Argument #1 ($locale) must be of type str TypeError: msgfmt_create(): Argument #1 ($locale) must be of type string, array given in %s on line %d 'U_ZERO_ERROR' -IntlException: pattern syntax error (parse error at offset 1, after "{", before or at "0,choice}"): U_PATTERN_SYNTAX_ERROR in %s on line %d -'pattern syntax error (parse error at offset 1, after "{", before or at "0,choice}"): U_PATTERN_SYNTAX_ERROR' -'pattern syntax error (parse error at offset 1, after "{", before or at "0,choice}"): U_PATTERN_SYNTAX_ERROR' -'pattern syntax error (parse error at offset 1, after "{", before or at "0,choice}"): U_PATTERN_SYNTAX_ERROR' +IntlException: MessageFormatter::__construct(): pattern syntax error (parse error at offset 1, after "{", before or at "0,choice}") in %s on line %d +'MessageFormatter::__construct(): pattern syntax error (parse error at offset 1, after "{", before or at "0,choice}"): U_PATTERN_SYNTAX_ERROR' +'MessageFormatter::create(): pattern syntax error (parse error at offset 1, after "{", before or at "0,choice}"): U_PATTERN_SYNTAX_ERROR' +'msgfmt_create(): pattern syntax error (parse error at offset 1, after "{", before or at "0,choice}"): U_PATTERN_SYNTAX_ERROR' -IntlException: msgfmt_create: message formatter creation failed: U_UNMATCHED_BRACES in %s on line %d -'msgfmt_create: message formatter creation failed: U_UNMATCHED_BRACES' -'msgfmt_create: message formatter creation failed: U_UNMATCHED_BRACES' -'msgfmt_create: message formatter creation failed: U_UNMATCHED_BRACES' +IntlException: MessageFormatter::__construct(): message formatter creation failed in %s on line %d +'MessageFormatter::__construct(): message formatter creation failed: U_UNMATCHED_BRACES' +'MessageFormatter::create(): message formatter creation failed: U_UNMATCHED_BRACES' +'msgfmt_create(): message formatter creation failed: U_UNMATCHED_BRACES' -IntlException: msgfmt_create: error converting pattern to UTF-16: U_INVALID_CHAR_FOUND in %s on line %d -'msgfmt_create: error converting pattern to UTF-16: U_INVALID_CHAR_FOUND' -'msgfmt_create: error converting pattern to UTF-16: U_INVALID_CHAR_FOUND' -'msgfmt_create: error converting pattern to UTF-16: U_INVALID_CHAR_FOUND' +IntlException: MessageFormatter::__construct(): error converting pattern to UTF-16 in %s on line %d +'MessageFormatter::__construct(): error converting pattern to UTF-16: U_INVALID_CHAR_FOUND' +'MessageFormatter::create(): error converting pattern to UTF-16: U_INVALID_CHAR_FOUND' +'msgfmt_create(): error converting pattern to UTF-16: U_INVALID_CHAR_FOUND' diff --git a/ext/intl/tests/msgfmt_format.phpt b/ext/intl/tests/msgfmt_format.phpt index 39efaf36c4e..99440a882e3 100644 --- a/ext/intl/tests/msgfmt_format.phpt +++ b/ext/intl/tests/msgfmt_format.phpt @@ -17,13 +17,13 @@ function ut_main() 'ru_UA' => "{0,number,integer} мавп на {1,number,integer} деревах це {2,number} мавпи на кожному деревi", 'de' => "{0,number,integer} Affen über {1,number,integer} Bäume um {2,number} Affen pro Baum", 'en_UK' => "{0,number,integer} monkeys on {1,number,integer} trees make {2,number} monkeys per tree", - 'root' => '{0,whatever} would not work!', - 'fr' => "C'est la vie!", + 'fr' => "C'est la vie!", ); $str_res = ''; $m = 4560; $t = 123; + $v = [$m, $t, $m/$t]; foreach( $locales as $locale => $pattern ) { @@ -33,8 +33,8 @@ function ut_main() $str_res .= dump(intl_get_error_message())."\n"; continue; } - $str_res .= dump( ut_msgfmt_format( $fmt, array($m, $t, $m/$t) ) ) . "\n"; - $str_res .= dump( ut_msgfmt_format_message($locale, $pattern, array($m, $t, $m/$t))) . "\n"; + $str_res .= dump( ut_msgfmt_format( $fmt, $v) ) . "\n"; + $str_res .= dump( ut_msgfmt_format_message($locale, $pattern, $v)) . "\n"; } return $str_res; } @@ -62,9 +62,6 @@ Locale is: en_UK '4,560 monkeys on 123 trees make 37.073 monkeys per tree' '4,560 monkeys on 123 trees make 37.073 monkeys per tree' -Locale is: root -'msgfmt_create: message formatter creation failed: U_ILLEGAL_ARGUMENT_ERROR' - Locale is: fr 'C\'est la vie!' 'C\'est la vie!' diff --git a/ext/intl/tests/msgfmt_format_datetime.phpt b/ext/intl/tests/msgfmt_format_datetime.phpt index e6a7451906f..7ee35e643e2 100644 --- a/ext/intl/tests/msgfmt_format_datetime.phpt +++ b/ext/intl/tests/msgfmt_format_datetime.phpt @@ -1,15 +1,11 @@ --TEST-- MessageFormatter::format(): DateTime accepted to format dates and times ---INI-- -date.timezone=Atlantic/Azores --EXTENSIONS-- intl --SKIPIF-- = 0) die('skip for ICU < 72.1'); ?> --FILE-- = 72.1'); ?> --FILE-- format(array(7))); +try { + var_dump($mf->format(array(7))); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; +} ?> ---EXPECTF-- -Warning: MessageFormatter::format(): Inconsistent types declared for an argument in %s on line %d -bool(false) +--EXPECT-- +IntlException: MessageFormatter::format(): Inconsistent types declared for an argument diff --git a/ext/intl/tests/msgfmt_format_error3.phpt b/ext/intl/tests/msgfmt_format_error3.phpt index f9c44789dc2..a03b0a21ecc 100644 --- a/ext/intl/tests/msgfmt_format_error3.phpt +++ b/ext/intl/tests/msgfmt_format_error3.phpt @@ -2,17 +2,21 @@ MessageFormatter::format() given negative arg key --EXTENSIONS-- intl +--INI-- +intl.use_exceptions=On --FILE-- format(array("foo" => 7, -1 => "bar"))); +try { + var_dump($mf->format(array("foo" => 7, -1 => "bar"))); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; +} ?> ---EXPECTF-- -Warning: MessageFormatter::format(): Found negative or too large array key in %s on line %d -bool(false) +--EXPECT-- +IntlException: MessageFormatter::format(): Found negative or too large array key diff --git a/ext/intl/tests/msgfmt_format_error4.phpt b/ext/intl/tests/msgfmt_format_error4.phpt index a6f59127230..451a55ad9da 100644 --- a/ext/intl/tests/msgfmt_format_error4.phpt +++ b/ext/intl/tests/msgfmt_format_error4.phpt @@ -2,22 +2,32 @@ MessageFormatter::format() invalid UTF-8 for arg key or value --EXTENSIONS-- intl +--INI-- +intl.use_exceptions=On --FILE-- format(array("foo" => 7, "\x80" => "bar"))); +try { + var_dump($mf->format(array("foo" => 7, "\x80" => "bar"))); +} catch (Throwable $e) { + var_dump($e::class === 'IntlException'); + var_dump("MessageFormatter::format(): Invalid UTF-8 data in argument key: '\x80'" === $e->getMessage()); +} -var_dump($mf->format(array("foo" => "\x80"))); +try { + var_dump($mf->format(array("foo" => "\x80"))); +} catch (Throwable $e) { + var_dump($e::class === 'IntlException'); + var_dump("MessageFormatter::format(): Invalid UTF-8 data in string argument: '\x80'" === $e->getMessage()); +} ?> ---EXPECTF-- -Warning: MessageFormatter::format(): Invalid UTF-8 data in argument key: '' in %s on line %d -bool(false) - -Warning: MessageFormatter::format(): Invalid UTF-8 data in string argument: '' in %s on line %d -bool(false) +--EXPECT-- +bool(true) +bool(true) +bool(true) +bool(true) diff --git a/ext/intl/tests/msgfmt_format_error5.phpt b/ext/intl/tests/msgfmt_format_error5.phpt index f3f87835b92..d5d7e6a4dc8 100644 --- a/ext/intl/tests/msgfmt_format_error5.phpt +++ b/ext/intl/tests/msgfmt_format_error5.phpt @@ -2,21 +2,22 @@ MessageFormatter::format() invalid date/time argument --INI-- date.timezone=Atlantic/Azores +intl.use_exceptions=On --EXTENSIONS-- intl --FILE-- format(array("foo" => new stdclass()))); +try { + var_dump($mf->format(array("foo" => new stdclass()))); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; +} ?> ---EXPECTF-- -Warning: MessageFormatter::format(): msgfmt_format: invalid object type for date/time (only IntlCalendar and DateTimeInterface permitted) in %s on line %d - -Warning: MessageFormatter::format(): The argument for key 'foo' cannot be used as a date or time in %s on line %d -bool(false) +--EXPECT-- +IntlException: MessageFormatter::format(): The argument for key 'foo' cannot be used as a date or time diff --git a/ext/intl/tests/msgfmt_format_error6.phpt b/ext/intl/tests/msgfmt_format_error6.phpt index 23db3972822..9320194be6f 100644 --- a/ext/intl/tests/msgfmt_format_error6.phpt +++ b/ext/intl/tests/msgfmt_format_error6.phpt @@ -2,17 +2,21 @@ MessageFormatter::format() invalid type for key not in pattern --EXTENSIONS-- intl +--INI-- +intl.use_exceptions=On --FILE-- format(array("foo" => 'bar', 7 => fopen('php://memory', 'r+')))); +try { + var_dump($mf->format(array("foo" => 'bar', 7 => fopen('php://memory', 'r+')))); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; +} ?> ---EXPECTF-- -Warning: MessageFormatter::format(): No strategy to convert the value given for the argument with key '7' is available in %s on line %d -bool(false) +--EXPECT-- +IntlException: MessageFormatter::format(): No strategy to convert the value given for the argument with key '7' is available diff --git a/ext/intl/tests/msgfmt_format_intlcalendar_variant4.phpt b/ext/intl/tests/msgfmt_format_intlcalendar_variant4.phpt index 0b8e607ad2d..014bdd4749b 100644 --- a/ext/intl/tests/msgfmt_format_intlcalendar_variant4.phpt +++ b/ext/intl/tests/msgfmt_format_intlcalendar_variant4.phpt @@ -2,6 +2,8 @@ MessageFormat accepts IntlCalendar args --EXTENSIONS-- intl +--INI-- +date.timezone=Europe/Lisbon --SKIPIF-- --FILE-- +--EXPECT-- +bool(false) +string(82) "MessageFormatter::formatMessage(): Creating message formatter failed: U_ZERO_ERROR" +bool(false) +string(72) "msgfmt_format_message(): Creating message formatter failed: U_ZERO_ERROR" diff --git a/ext/intl/tests/msgfmt_format_mixed_params.phpt b/ext/intl/tests/msgfmt_format_mixed_params.phpt index 016dbe96be4..3cfb2100999 100644 --- a/ext/intl/tests/msgfmt_format_mixed_params.phpt +++ b/ext/intl/tests/msgfmt_format_mixed_params.phpt @@ -4,8 +4,6 @@ MessageFormatter::format(): mixed named and numeric parameters intl --FILE-- = 0) die('skip for ICU < 72.1'); ?> --FILE-- = 72.1'); ?> --FILE-- "{0,number,integer} мавп на {1,number,integer} деревах це {2,number} мавпи на кожному деревi", 'de' => "{0,number,integer} Affen über {1,number,integer} Bäume um {2,number} Affen pro Baum", 'en_UK' => "{0,number,integer} monkeys on {1,number,integer} trees make {2,number} monkeys per tree", - 'root' => '{0,whatever} would not work!', - 'fr' => 'C\'est {0,number,integer}', + 'fr' => 'C\'est {0,number,integer}', ); $results = array( @@ -26,7 +25,6 @@ function ut_main() 'ru_UA' => "4 560 мавп на 123 деревах це 37,073 мавпи на кожному деревi", 'de' => "4.560 Affen über 123 Bäume um 37,073 Affen pro Baum", 'en_UK' => "4,560 monkeys on 123 trees make 37.073 monkeys per tree", - 'root' => "4,560 monkeys on 123 trees make 37.073 monkeys per tree", 'fr' => "C'est 42", ); @@ -102,9 +100,6 @@ array ( 2 => 37.073, ) -Locale is: root -'msgfmt_create: message formatter creation failed: U_ILLEGAL_ARGUMENT_ERROR' - Locale is: fr array ( 0 => 42, diff --git a/ext/intl/tests/msgfmt_parse_message_errors.phpt b/ext/intl/tests/msgfmt_parse_message_errors.phpt new file mode 100644 index 00000000000..7bd0780fa64 --- /dev/null +++ b/ext/intl/tests/msgfmt_parse_message_errors.phpt @@ -0,0 +1,27 @@ +--TEST-- +MessageFormatter::parseMessage() with invalid locale +--EXTENSIONS-- +intl +--CREDITS-- +girgias@php.net +--FILE-- + +--EXPECT-- +bool(false) +string(93) "MessageFormatter::parseMessage(): Creating message formatter failed: U_ILLEGAL_ARGUMENT_ERROR" +bool(false) +string(83) "msgfmt_parse_message(): Creating message formatter failed: U_ILLEGAL_ARGUMENT_ERROR" diff --git a/ext/intl/tests/msgfmt_setPattern_cache.phpt b/ext/intl/tests/msgfmt_setPattern_cache.phpt index 7aff410f082..9b5af254203 100644 --- a/ext/intl/tests/msgfmt_setPattern_cache.phpt +++ b/ext/intl/tests/msgfmt_setPattern_cache.phpt @@ -4,8 +4,6 @@ MessageFormatter::setPattern() invalidates arg types cache intl --FILE-- setPattern($broken); +var_dump($mf->getErrorMessage()); + +msgfmt_set_pattern($mf, $broken); +var_dump($mf->getErrorMessage()); + +?> +--EXPECT-- +string(103) "MessageFormatter::setPattern(): Error setting symbol value at line 0, offset 26: U_PATTERN_SYNTAX_ERROR" +string(93) "msgfmt_set_pattern(): Error setting symbol value at line 0, offset 26: U_PATTERN_SYNTAX_ERROR" diff --git a/ext/intl/tests/normalizer_get_raw_decomposition.phpt b/ext/intl/tests/normalizer_get_raw_decomposition.phpt index efb4424c80c..678a85491fd 100644 --- a/ext/intl/tests/normalizer_get_raw_decomposition.phpt +++ b/ext/intl/tests/normalizer_get_raw_decomposition.phpt @@ -2,67 +2,52 @@ normalizer_get_raw_decomposition() --EXTENSIONS-- intl ---SKIPIF-- - --FILE-- --EXPECT-- ---------------------- -'61' has no decomposition mapping -error info: 'U_ZERO_ERROR' (0) ---------------------- -'efbf9a' has the decomposition mapping 'e385a1' -error info: 'U_ZERO_ERROR' (0) ---------------------- -'efb7ba' has the decomposition mapping 'd8b5d984d98920d8a7d984d984d98720d8b9d984d98ad98720d988d8b3d984d985' -error info: 'U_ZERO_ERROR' (0) ---------------------- -'' has no decomposition mapping -error info: 'Input string must be exactly one UTF-8 encoded code point long.: U_ILLEGAL_ARGUMENT_ERROR' (1) ---------------------- -'6161' has no decomposition mapping -error info: 'Input string must be exactly one UTF-8 encoded code point long.: U_ILLEGAL_ARGUMENT_ERROR' (1) ---------------------- -'f5' has no decomposition mapping -error info: 'Code point out of range: U_ILLEGAL_ARGUMENT_ERROR' (1) +'a' has no decomposition mapping +'a' has no decomposition mapping +string(3) "ㅡ" +string(3) "ㅡ" +string(33) "صلى الله عليه وسلم" +string(33) "صلى الله عليه وسلم" +string(124) "Normalizer::getRawDecomposition(): Input string must be exactly one UTF-8 encoded code point long.: U_ILLEGAL_ARGUMENT_ERROR" +string(125) "normalizer_get_raw_decomposition(): Input string must be exactly one UTF-8 encoded code point long.: U_ILLEGAL_ARGUMENT_ERROR" +string(124) "Normalizer::getRawDecomposition(): Input string must be exactly one UTF-8 encoded code point long.: U_ILLEGAL_ARGUMENT_ERROR" +string(125) "normalizer_get_raw_decomposition(): Input string must be exactly one UTF-8 encoded code point long.: U_ILLEGAL_ARGUMENT_ERROR" +string(84) "Normalizer::getRawDecomposition(): Code point out of range: U_ILLEGAL_ARGUMENT_ERROR" +string(85) "normalizer_get_raw_decomposition(): Code point out of range: U_ILLEGAL_ARGUMENT_ERROR" diff --git a/ext/intl/tests/rbbiter___construct_basic.phpt b/ext/intl/tests/rbbiter___construct_basic.phpt index 6d2361f667b..e749442daa9 100644 --- a/ext/intl/tests/rbbiter___construct_basic.phpt +++ b/ext/intl/tests/rbbiter___construct_basic.phpt @@ -2,9 +2,10 @@ IntlRuleBasedBreakIterator::__construct: basic test --EXTENSIONS-- intl +--INI-- +intl.default_locale=pt_PT --FILE-- = 0) die('skip for ICU < 61.1'); ?> --FILE-- = 61.1 && icu < 68.1 --EXTENSIONS-- intl +--INI-- +intl.default_locale=pt_PT --SKIPIF-- = 61.1'; ?> = 0) die('skip for ICU < 68.1'); ?> --FILE-- = 68.1 --EXTENSIONS-- intl +--INI-- +intl.default_locale=pt_PT --SKIPIF-- = 68.1'); ?> --FILE-- = 0) die('skip for ICU < 61.1'); ?> --FILE-- = 61.1 && icu < 68.1 --EXTENSIONS-- intl +--INI-- +intl.default_locale=pt_PT --SKIPIF-- = 61.1'); ?> = 0) die('skip for ICU < 68.1'); ?> --FILE-- = 68.1 --EXTENSIONS-- intl +--INI-- +intl.default_locale=pt_PT --SKIPIF-- = 68.1'); ?> --FILE-- getMessage(), PHP_EOL; +} + +$rb = resourcebundle_create('en_US', 'non-existing'); +var_dump($rb); +var_dump(intl_get_error_message()); + +require_once "resourcebundle.inc"; + +try { + $rb = new ResourceBundle('en_US', BUNDLE, false); + var_dump($rb); + var_dump(intl_get_error_message()); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; +} + +$rb = resourcebundle_create('en_US', BUNDLE, false); +var_dump($rb); +var_dump(intl_get_error_message()); + +?> +--EXPECT-- +IntlException: ResourceBundle::__construct(): Cannot load libICU resource bundle +NULL +string(85) "resourcebundle_create(): Cannot load libICU resource bundle: U_MISSING_RESOURCE_ERROR" +IntlException: ResourceBundle::__construct(): Cannot load libICU resource bundle +NULL +string(85) "resourcebundle_create(): Cannot load libICU resource bundle: U_MISSING_RESOURCE_ERROR" diff --git a/ext/intl/tests/resourcebundle_get_errors.phpt b/ext/intl/tests/resourcebundle_get_errors.phpt new file mode 100644 index 00000000000..28952b81610 --- /dev/null +++ b/ext/intl/tests/resourcebundle_get_errors.phpt @@ -0,0 +1,25 @@ +--TEST-- +Test ResourceBundle::get() missing keys +--EXTENSIONS-- +intl +--FILE-- +get('nonexisting')); +var_dump(intl_get_error_message()); + +var_dump(resourcebundle_get($bundle, 'nonexisting')); +var_dump(intl_get_error_message()); + +// Make sure accessing existing after non-existing works. +var_dump($bundle->get('teststring')); + +?> +--EXPECT-- +NULL +string(91) "ResourceBundle::get(): Cannot load resource element 'nonexisting': U_MISSING_RESOURCE_ERROR" +NULL +string(90) "resourcebundle_get(): Cannot load resource element 'nonexisting': U_MISSING_RESOURCE_ERROR" +string(12) "Hello World!" diff --git a/ext/intl/tests/resourcebundle_individual.phpt b/ext/intl/tests/resourcebundle_individual.phpt index d9be94b464b..089c485dc8a 100644 --- a/ext/intl/tests/resourcebundle_individual.phpt +++ b/ext/intl/tests/resourcebundle_individual.phpt @@ -1,5 +1,5 @@ --TEST-- -Test ResourceBundle::get() and length() - existing/missing keys +Test ResourceBundle::get() and length() - existing keys --EXTENSIONS-- intl --FILE-- @@ -25,13 +25,6 @@ function ut_main() { $r2 = ut_resourcebundle_get($r,'testarray' ); $str_res .= sprintf( "testarray: %s\n", ut_resourcebundle_get($r2, 2 ) ); - $t = ut_resourcebundle_get( $r, 'nonexisting' ); - $str_res .= debug( $t ); - - // Make sure accessing existing after non-existing works. - $t = ut_resourcebundle_get( $r, 'teststring' ); - $str_res .= debug( $t ); - return $str_res; } include_once( 'ut_common.inc' ); @@ -57,7 +50,3 @@ Array testbin: a1b2c3d4e5f67890 testtable: 3 testarray: string 3 -NULL - 2: Cannot load resource element 'nonexisting': U_MISSING_RESOURCE_ERROR -Hello World! - 0: U_ZERO_ERROR diff --git a/ext/intl/tests/resourcebundle_null_mandatory_args_variant2.phpt b/ext/intl/tests/resourcebundle_null_mandatory_args_variant2.phpt index 9d13be94aed..b49e30317b3 100644 --- a/ext/intl/tests/resourcebundle_null_mandatory_args_variant2.phpt +++ b/ext/intl/tests/resourcebundle_null_mandatory_args_variant2.phpt @@ -8,7 +8,6 @@ intl = 0) die('skip for ICU < 72.1'); ?> --FILE-- get('calendar')->get('gregorian')->get('DateTimePatterns')->get(0); diff --git a/ext/intl/tests/resourcebundle_null_mandatory_args_variant_icu72-1.phpt b/ext/intl/tests/resourcebundle_null_mandatory_args_variant_icu72-1.phpt index d3e2615e0f4..98fa0c47305 100644 --- a/ext/intl/tests/resourcebundle_null_mandatory_args_variant_icu72-1.phpt +++ b/ext/intl/tests/resourcebundle_null_mandatory_args_variant_icu72-1.phpt @@ -8,7 +8,6 @@ intl = 72.1'); ?> --FILE-- get('calendar')->get('gregorian')->get('DateTimePatterns')->get(0); diff --git a/ext/intl/tests/timezone_IDforWindowsID_basic.phpt b/ext/intl/tests/timezone_IDforWindowsID_basic.phpt index 8626223cb8b..8e1fcbb4a8f 100644 --- a/ext/intl/tests/timezone_IDforWindowsID_basic.phpt +++ b/ext/intl/tests/timezone_IDforWindowsID_basic.phpt @@ -8,7 +8,6 @@ intl array(NULL), 'India Standard Time' => array(NULL), 'Pacific Standard Time' => array('001', 'CA', 'MX', 'US', 'ZZ'), 'Romance Standard Time' => array('001', 'BE', 'DK', 'ES', 'FR'), @@ -25,9 +24,6 @@ foreach ($tzs as $tz => $regions) { } ?> --EXPECT-- -** Gnomeregan -bool(false) -Error: intltz_get_windows_id: Unknown windows timezone: U_ILLEGAL_ARGUMENT_ERROR ** India Standard Time string(13) "Asia/Calcutta" ** Pacific Standard Time diff --git a/ext/intl/tests/timezone_IDforWindowsID_basic2.phpt b/ext/intl/tests/timezone_IDforWindowsID_basic_icu58_1.phpt similarity index 91% rename from ext/intl/tests/timezone_IDforWindowsID_basic2.phpt rename to ext/intl/tests/timezone_IDforWindowsID_basic_icu58_1.phpt index 600e21fa70c..b92ebb89ec2 100644 --- a/ext/intl/tests/timezone_IDforWindowsID_basic2.phpt +++ b/ext/intl/tests/timezone_IDforWindowsID_basic_icu58_1.phpt @@ -9,7 +9,6 @@ intl array(NULL), 'India Standard Time' => array(NULL), 'Pacific Standard Time' => array('001', 'CA', 'MX', 'US', 'ZZ'), 'Romance Standard Time' => array('001', 'BE', 'DK', 'ES', 'FR'), @@ -26,9 +25,6 @@ foreach ($tzs as $tz => $regions) { } ?> --EXPECTF-- -** Gnomeregan -bool(false) -Error: unknown windows timezone: U_ILLEGAL_ARGUMENT_ERROR ** India Standard Time string(13) "Asia/Calcutta" ** Pacific Standard Time diff --git a/ext/intl/tests/timezone_IDforWindowsID_basic_icu76_1.phpt b/ext/intl/tests/timezone_IDforWindowsID_basic_icu76_1.phpt index 96de341974b..d07c14797c6 100644 --- a/ext/intl/tests/timezone_IDforWindowsID_basic_icu76_1.phpt +++ b/ext/intl/tests/timezone_IDforWindowsID_basic_icu76_1.phpt @@ -8,7 +8,6 @@ intl array(NULL), 'India Standard Time' => array(NULL), 'Pacific Standard Time' => array('001', 'CA', 'MX', 'US', 'ZZ'), 'Romance Standard Time' => array('001', 'BE', 'DK', 'ES', 'FR'), @@ -24,10 +23,7 @@ foreach ($tzs as $tz => $regions) { } } ?> ---EXPECTF-- -** Gnomeregan -bool(false) -Error: %snknown windows timezone: U_ILLEGAL_ARGUMENT_ERROR +--EXPECT-- ** India Standard Time string(13) "Asia/Calcutta" ** Pacific Standard Time diff --git a/ext/intl/tests/timezone_IDforWindowsID_error.phpt b/ext/intl/tests/timezone_IDforWindowsID_error.phpt new file mode 100644 index 00000000000..1160ce9f91a --- /dev/null +++ b/ext/intl/tests/timezone_IDforWindowsID_error.phpt @@ -0,0 +1,14 @@ +--TEST-- +IntlTimeZone::getIDForWindowsID() errors +--EXTENSIONS-- +intl +--FILE-- + +--EXPECT-- +bool(false) +string(85) "IntlTimeZone::getIDForWindowsID(): unknown windows timezone: U_ILLEGAL_ARGUMENT_ERROR" diff --git a/ext/intl/tests/timezone_clone_basic.phpt b/ext/intl/tests/timezone_clone_basic.phpt index c09ffe46203..db13884d272 100644 --- a/ext/intl/tests/timezone_clone_basic.phpt +++ b/ext/intl/tests/timezone_clone_basic.phpt @@ -4,7 +4,6 @@ IntlTimeZone clone handler: basic test intl --FILE-- GMT [rawOffset] => 0 [currentOffset] => 0 -) \ No newline at end of file +) diff --git a/ext/intl/tests/timezone_countEquivalentIDs_basic.phpt b/ext/intl/tests/timezone_countEquivalentIDs_basic.phpt index 2fa3a7d249f..25fa0f8839b 100644 --- a/ext/intl/tests/timezone_countEquivalentIDs_basic.phpt +++ b/ext/intl/tests/timezone_countEquivalentIDs_basic.phpt @@ -4,7 +4,6 @@ IntlTimeZone::countEquivalentIDs(): basic test intl --FILE-- = 2); @@ -13,4 +12,4 @@ var_dump($count2 == $count); ?> --EXPECT-- bool(true) -bool(true) \ No newline at end of file +bool(true) diff --git a/ext/intl/tests/timezone_countEquivalentIDs_error.phpt b/ext/intl/tests/timezone_countEquivalentIDs_error.phpt index 23f95e129f1..5eab5f881da 100644 --- a/ext/intl/tests/timezone_countEquivalentIDs_error.phpt +++ b/ext/intl/tests/timezone_countEquivalentIDs_error.phpt @@ -4,10 +4,11 @@ IntlTimeZone::countEquivalentIDs(): errors intl --FILE-- ---EXPECTF-- -Warning: IntlTimeZone::countEquivalentIDs(): could not convert time zone id to UTF-16 in %s on line %d +--EXPECT-- bool(false) +IntlTimeZone::countEquivalentIDs(): could not convert time zone id to UTF-16: U_INVALID_CHAR_FOUND diff --git a/ext/intl/tests/timezone_createDefault_basic.phpt b/ext/intl/tests/timezone_createDefault_basic.phpt index 82ba9c94564..2281e9e35bf 100644 --- a/ext/intl/tests/timezone_createDefault_basic.phpt +++ b/ext/intl/tests/timezone_createDefault_basic.phpt @@ -4,7 +4,6 @@ IntlTimeZone::createDefault(): basic test intl --FILE-- getMessage(), PHP_EOL; +} + +try { + var_dump(IntlTimeZone::createEnumeration(new stdClass())); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; +} ?> ---EXPECTF-- -Warning: IntlTimeZone::createEnumeration(): invalid argument type in %s on line %d -bool(false) +--EXPECT-- +TypeError: IntlTimeZone::createEnumeration(): Argument #1 ($countryOrRawOffset) must be of type string|int|null, array given +TypeError: IntlTimeZone::createEnumeration(): Argument #1 ($countryOrRawOffset) must be of type string|int|null, stdClass given diff --git a/ext/intl/tests/timezone_createEnumeration_variation1.phpt b/ext/intl/tests/timezone_createEnumeration_variation1.phpt index 5dfe9f893e0..96a73779bfa 100644 --- a/ext/intl/tests/timezone_createEnumeration_variation1.phpt +++ b/ext/intl/tests/timezone_createEnumeration_variation1.phpt @@ -4,7 +4,6 @@ IntlTimeZone::createEnumeration(): variant with offset intl --FILE-- --EXPECT-- -Array -( - [0] => Atlantic/Azores -) -Array -( - [0] => Atlantic/Azores -) +array(1) { + [0]=> + string(15) "Atlantic/Azores" +} +array(1) { + [0]=> + string(15) "Atlantic/Azores" +} diff --git a/ext/intl/tests/timezone_createTimeZoneIDEnumeration_error.phpt b/ext/intl/tests/timezone_createTimeZoneIDEnumeration_error.phpt index 2173c4a5cd1..0eb26b826a3 100644 --- a/ext/intl/tests/timezone_createTimeZoneIDEnumeration_error.phpt +++ b/ext/intl/tests/timezone_createTimeZoneIDEnumeration_error.phpt @@ -1,13 +1,16 @@ --TEST-- -IntlTimeZone::createTimeZoneIDEnumeration(): errors +IntlTimeZone::createTimeZoneIDEnumeration() invalid zone type --EXTENSIONS-- intl --FILE-- getMessage(), PHP_EOL; +} + ?> ---EXPECTF-- -Warning: IntlTimeZone::createTimeZoneIDEnumeration(): bad zone type in %s on line %d -bool(false) +--EXPECT-- +ValueError: IntlTimeZone::createTimeZoneIDEnumeration(): Argument #1 ($type) must be one of IntlTimeZone::TYPE_ANY, IntlTimeZone::TYPE_CANONICAL, or IntlTimeZone::TYPE_CANONICAL_LOCATION diff --git a/ext/intl/tests/timezone_createTimeZoneIDEnumeration_error_64bit.phpt b/ext/intl/tests/timezone_createTimeZoneIDEnumeration_error_64bit.phpt new file mode 100644 index 00000000000..1e6791a172c --- /dev/null +++ b/ext/intl/tests/timezone_createTimeZoneIDEnumeration_error_64bit.phpt @@ -0,0 +1,17 @@ +--TEST-- +IntlTimeZone::createTimeZoneIDEnumeration() offset out of range +--EXTENSIONS-- +intl +--SKIPIF-- + +--FILE-- +getMessage(), PHP_EOL; +} +?> +--EXPECT-- +ValueError: IntlTimeZone::createTimeZoneIDEnumeration(): Argument #3 ($rawOffset) must be between -2147483648 and 2147483647 diff --git a/ext/intl/tests/timezone_createTimeZoneIDEnumeration_variant1.phpt b/ext/intl/tests/timezone_createTimeZoneIDEnumeration_variant1.phpt index ff940aa725d..34523d0037d 100644 --- a/ext/intl/tests/timezone_createTimeZoneIDEnumeration_variant1.phpt +++ b/ext/intl/tests/timezone_createTimeZoneIDEnumeration_variant1.phpt @@ -4,7 +4,6 @@ IntlTimeZone::createTimeZoneIDEnumeration(): variant without offset intl --FILE-- Atlantic/Azores - [1] => Etc/GMT+1 -) +array(2) { + [0]=> + string(15) "Atlantic/Azores" + [1]=> + string(9) "Etc/GMT+1" +} diff --git a/ext/intl/tests/timezone_createTimeZone_basic.phpt b/ext/intl/tests/timezone_createTimeZone_basic.phpt index c3ffe289672..1a3549cafdf 100644 --- a/ext/intl/tests/timezone_createTimeZone_basic.phpt +++ b/ext/intl/tests/timezone_createTimeZone_basic.phpt @@ -4,7 +4,6 @@ IntlTimeZone::createTimeZone(): basic test intl --FILE-- ---EXPECTF-- -Warning: IntlTimeZone::createTimeZone(): could not convert time zone id to UTF-16 in %s on line %d +--EXPECT-- NULL +IntlTimeZone::createTimeZone(): could not convert time zone id to UTF-16: U_INVALID_CHAR_FOUND diff --git a/ext/intl/tests/timezone_equals_basic.phpt b/ext/intl/tests/timezone_equals_basic.phpt index 04636a4f7c4..224f9c9229a 100644 --- a/ext/intl/tests/timezone_equals_basic.phpt +++ b/ext/intl/tests/timezone_equals_basic.phpt @@ -4,7 +4,6 @@ IntlTimeZone equals handler: basic test intl --FILE-- getMessage()); + var_dump($tz == $tz2); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; } ?> @@ -35,5 +34,4 @@ object(IntlTimeZone)#2 (4) { ["currentOffset"]=> int(0) } -string(9) "Exception" -string(63) "Comparison with at least one unconstructed IntlTimeZone operand" \ No newline at end of file +Exception: Comparison with at least one unconstructed IntlTimeZone operand diff --git a/ext/intl/tests/timezone_fromDateTimeZone_basic.phpt b/ext/intl/tests/timezone_fromDateTimeZone_basic.phpt index 45443c78a16..3e9597de0bb 100644 --- a/ext/intl/tests/timezone_fromDateTimeZone_basic.phpt +++ b/ext/intl/tests/timezone_fromDateTimeZone_basic.phpt @@ -2,11 +2,11 @@ IntlTimeZone::fromDateTimeZone(): basic test --EXTENSIONS-- intl +--INI-- +date.timezone=Europe/Lisbon +intl.default_locale=nl --FILE-- getID(), $tz->getRawOffset()); diff --git a/ext/intl/tests/timezone_fromDateTimeZone_error.phpt b/ext/intl/tests/timezone_fromDateTimeZone_error.phpt index fe2a0445303..acd608bc376 100644 --- a/ext/intl/tests/timezone_fromDateTimeZone_error.phpt +++ b/ext/intl/tests/timezone_fromDateTimeZone_error.phpt @@ -6,11 +6,12 @@ date.timezone=Atlantic/Azores intl --FILE-- getTimeZone())); +var_dump(intl_get_error_message()); + ?> ---EXPECTF-- -Warning: IntlTimeZone::fromDateTimeZone(): intltz_from_date_time_zone: time zone id 'WEST' extracted from ext/date DateTimeZone not recognized in %s on line %d +--EXPECT-- NULL +string(131) "IntlTimeZone::fromDateTimeZone(): time zone id 'WEST' extracted from ext/date DateTimeZone not recognized: U_ILLEGAL_ARGUMENT_ERROR" diff --git a/ext/intl/tests/timezone_getCanonicalID_basic.phpt b/ext/intl/tests/timezone_getCanonicalID_basic.phpt index 7660b04e264..0bc18e4c8b6 100644 --- a/ext/intl/tests/timezone_getCanonicalID_basic.phpt +++ b/ext/intl/tests/timezone_getCanonicalID_basic.phpt @@ -4,7 +4,6 @@ IntlTimeZone::getCanonicalID: basic test intl --FILE-- --EXPECT-- Europe/Lisbon -Europe/Lisbon \ No newline at end of file +Europe/Lisbon diff --git a/ext/intl/tests/timezone_getCanonicalID_error.phpt b/ext/intl/tests/timezone_getCanonicalID_error.phpt index d85805555a3..542d3ca3fa4 100644 --- a/ext/intl/tests/timezone_getCanonicalID_error.phpt +++ b/ext/intl/tests/timezone_getCanonicalID_error.phpt @@ -4,10 +4,11 @@ IntlTimeZone::getCanonicalID(): errors intl --FILE-- ---EXPECTF-- -Warning: IntlTimeZone::getCanonicalID(): could not convert time zone id to UTF-16 in %s on line %d +--EXPECT-- bool(false) +IntlTimeZone::getCanonicalID(): could not convert time zone id to UTF-16: U_INVALID_CHAR_FOUND diff --git a/ext/intl/tests/timezone_getCanonicalID_variant1_2.phpt b/ext/intl/tests/timezone_getCanonicalID_variant1_2.phpt index 3fedf437719..d883bb06ebd 100644 --- a/ext/intl/tests/timezone_getCanonicalID_variant1_2.phpt +++ b/ext/intl/tests/timezone_getCanonicalID_variant1_2.phpt @@ -4,20 +4,21 @@ IntlTimeZone::getCanonicalID(): second argument intl --FILE-- ---EXPECTF-- +--EXPECT-- string(13) "Europe/Lisbon" +U_ZERO_ERROR bool(true) - -Warning: IntlTimeZone::getCanonicalID(): error obtaining canonical ID in %stimezone_getCanonicalID_variant1_2.php on line %d bool(false) +IntlTimeZone::getCanonicalID(): error obtaining canonical ID: U_ILLEGAL_ARGUMENT_ERROR bool(true) diff --git a/ext/intl/tests/timezone_getDSTSavings_basic.phpt b/ext/intl/tests/timezone_getDSTSavings_basic.phpt index 1a0b5554322..469e4b5791c 100644 --- a/ext/intl/tests/timezone_getDSTSavings_basic.phpt +++ b/ext/intl/tests/timezone_getDSTSavings_basic.phpt @@ -4,7 +4,6 @@ IntlTimeZone::getDSTSavings(): basic test intl --FILE-- getDSTSavings()); @@ -14,4 +13,4 @@ var_dump(intltz_get_dst_savings($lsb)); ?> --EXPECT-- int(3600000) -int(3600000) \ No newline at end of file +int(3600000) diff --git a/ext/intl/tests/timezone_getDSTSavings_error.phpt b/ext/intl/tests/timezone_getDSTSavings_error.phpt deleted file mode 100644 index c444aab6453..00000000000 --- a/ext/intl/tests/timezone_getDSTSavings_error.phpt +++ /dev/null @@ -1,16 +0,0 @@ ---TEST-- -IntlTimeZone::getDSTSavings(): errors ---EXTENSIONS-- -intl ---FILE-- - ---EXPECTF-- -Fatal error: Uncaught TypeError: intltz_get_dst_savings(): Argument #1 ($timezone) must be of type IntlTimeZone, null given in %s:%d -Stack trace: -#0 %s(%d): intltz_get_dst_savings(NULL) -#1 {main} - thrown in %s on line %d diff --git a/ext/intl/tests/timezone_getDisplayName_basic.phpt b/ext/intl/tests/timezone_getDisplayName_basic.phpt index 6db1596b380..a80eeb762d1 100644 --- a/ext/intl/tests/timezone_getDisplayName_basic.phpt +++ b/ext/intl/tests/timezone_getDisplayName_basic.phpt @@ -4,7 +4,6 @@ IntlTimeZone::getDisplayName(): basic test intl --FILE-- getDisplayName()); ?> --EXPECTF-- string(%d) "Western European%sTime" -string(%d) "Hora%sda Europa Ocidental" \ No newline at end of file +string(%d) "Hora%sda Europa Ocidental" diff --git a/ext/intl/tests/timezone_getDisplayName_error.phpt b/ext/intl/tests/timezone_getDisplayName_error.phpt index ce3ab2f7e76..ca845b2830e 100644 --- a/ext/intl/tests/timezone_getDisplayName_error.phpt +++ b/ext/intl/tests/timezone_getDisplayName_error.phpt @@ -4,19 +4,12 @@ IntlTimeZone::getDisplayName(): errors intl --FILE-- getDisplayName(false, -1)); +echo intl_get_error_message(), PHP_EOL; -var_dump(intltz_get_display_name(null, IntlTimeZone::DISPLAY_SHORT, false, 'pt_PT')); ?> ---EXPECTF-- -Warning: IntlTimeZone::getDisplayName(): wrong display type in %s on line %d +--EXPECT-- bool(false) - -Fatal error: Uncaught TypeError: intltz_get_display_name(): Argument #1 ($timezone) must be of type IntlTimeZone, null given in %s:%d -Stack trace: -#0 %s(%d): intltz_get_display_name(NULL, 1, false, 'pt_PT') -#1 {main} - thrown in %s on line %d +IntlTimeZone::getDisplayName(): wrong display type: U_ILLEGAL_ARGUMENT_ERROR diff --git a/ext/intl/tests/timezone_getDisplayName_variant1.phpt b/ext/intl/tests/timezone_getDisplayName_variant1.phpt index 60c11ee9127..684e564779c 100644 --- a/ext/intl/tests/timezone_getDisplayName_variant1.phpt +++ b/ext/intl/tests/timezone_getDisplayName_variant1.phpt @@ -2,15 +2,13 @@ IntlTimeZone::getDisplayName(): daylight parameter effect --EXTENSIONS-- intl +--INI-- +intl.default_locale=en_US --FILE-- getDisplayName()); var_dump($lsb->getDisplayName(false)); var_dump($lsb->getDisplayName(true)); @@ -19,4 +17,4 @@ var_dump($lsb->getDisplayName(true)); --EXPECTF-- string(%d) "Western European%sTime" string(%d) "Western European%sTime" -string(28) "Western European Summer Time" \ No newline at end of file +string(28) "Western European Summer Time" diff --git a/ext/intl/tests/timezone_getDisplayName_variant4.phpt b/ext/intl/tests/timezone_getDisplayName_variant4.phpt index eccf6c78d2c..39d71f5aa20 100644 --- a/ext/intl/tests/timezone_getDisplayName_variant4.phpt +++ b/ext/intl/tests/timezone_getDisplayName_variant4.phpt @@ -2,15 +2,13 @@ IntlTimeZone::getDisplayName(): type parameter (ICU >= 51.2) --EXTENSIONS-- intl +--INI-- +intl.default_locale=en_US --FILE-- getDisplayName(false, IntlTimeZone::DISPLAY_SHORT)); var_dump($lsb->getDisplayName(false, IntlTimeZone::DISPLAY_LONG)); var_dump($lsb->getDisplayName(false, IntlTimeZone::DISPLAY_SHORT_GENERIC)); diff --git a/ext/intl/tests/timezone_getEquivalentID_basic.phpt b/ext/intl/tests/timezone_getEquivalentID_basic.phpt index 2e311bc8664..7702b01506e 100644 --- a/ext/intl/tests/timezone_getEquivalentID_basic.phpt +++ b/ext/intl/tests/timezone_getEquivalentID_basic.phpt @@ -4,12 +4,11 @@ IntlTimeZone::getEquivalentID(): basic test intl --FILE-- --EXPECT-- -Portugal -Portugal \ No newline at end of file +string(8) "Portugal" +string(8) "Portugal" diff --git a/ext/intl/tests/timezone_getEquivalentID_error.phpt b/ext/intl/tests/timezone_getEquivalentID_error.phpt index ebb85fb1334..c6b1a963daf 100644 --- a/ext/intl/tests/timezone_getEquivalentID_error.phpt +++ b/ext/intl/tests/timezone_getEquivalentID_error.phpt @@ -4,10 +4,11 @@ IntlTimeZone::getEquivalentID(): errors intl --FILE-- ---EXPECTF-- -Warning: IntlTimeZone::getEquivalentID(): could not convert time zone id to UTF-16 in %s on line %d +--EXPECT-- bool(false) +IntlTimeZone::getEquivalentID(): could not convert time zone id to UTF-16: U_INVALID_CHAR_FOUND diff --git a/ext/intl/tests/timezone_getErrorCodeMessage_basic.phpt b/ext/intl/tests/timezone_getErrorCodeMessage_basic.phpt index 597e9b51a0f..be991baf5f6 100644 --- a/ext/intl/tests/timezone_getErrorCodeMessage_basic.phpt +++ b/ext/intl/tests/timezone_getErrorCodeMessage_basic.phpt @@ -11,24 +11,23 @@ if ($arch != 'x86_64' && $arch != 'i386') ?> --FILE-- getErrorCode()); var_dump($lsb->getErrorMessage()); +echo "Call to getOffset():\n"; var_dump($lsb->getOffset(INF, 1, $a, $b)); var_dump($lsb->getErrorCode()); var_dump($lsb->getErrorMessage()); ?> ---EXPECTF-- +--EXPECT-- int(0) string(12) "U_ZERO_ERROR" - -Warning: IntlTimeZone::getOffset(): error obtaining offset in %s on line %d +Call to getOffset(): bool(false) int(1) -string(48) "error obtaining offset: U_ILLEGAL_ARGUMENT_ERROR" +string(75) "IntlTimeZone::getOffset(): error obtaining offset: U_ILLEGAL_ARGUMENT_ERROR" diff --git a/ext/intl/tests/timezone_getErrorCode_error.phpt b/ext/intl/tests/timezone_getErrorCode_error.phpt deleted file mode 100644 index 3b91977c69b..00000000000 --- a/ext/intl/tests/timezone_getErrorCode_error.phpt +++ /dev/null @@ -1,16 +0,0 @@ ---TEST-- -IntlTimeZone::getErrorCode(): errors ---EXTENSIONS-- -intl ---FILE-- - ---EXPECTF-- -Fatal error: Uncaught TypeError: intltz_get_error_code(): Argument #1 ($timezone) must be of type IntlTimeZone, null given in %s:%d -Stack trace: -#0 %s(%d): intltz_get_error_code(NULL) -#1 {main} - thrown in %s on line %d diff --git a/ext/intl/tests/timezone_getErrorMessage_error.phpt b/ext/intl/tests/timezone_getErrorMessage_error.phpt deleted file mode 100644 index 80c5ec02f5a..00000000000 --- a/ext/intl/tests/timezone_getErrorMessage_error.phpt +++ /dev/null @@ -1,16 +0,0 @@ ---TEST-- -IntlTimeZone::getErrorMessage(): errors ---EXTENSIONS-- -intl ---FILE-- - ---EXPECTF-- -Fatal error: Uncaught TypeError: intltz_get_error_message(): Argument #1 ($timezone) must be of type IntlTimeZone, null given in %s:%d -Stack trace: -#0 %s(%d): intltz_get_error_message(NULL) -#1 {main} - thrown in %s on line %d diff --git a/ext/intl/tests/timezone_getGMT_basic.phpt b/ext/intl/tests/timezone_getGMT_basic.phpt index becc52fd3e1..d58b555bbe2 100644 --- a/ext/intl/tests/timezone_getGMT_basic.phpt +++ b/ext/intl/tests/timezone_getGMT_basic.phpt @@ -4,7 +4,6 @@ IntlTimeZone::getGMT(): basic test intl --FILE-- GMT [rawOffset] => 0 [currentOffset] => 0 -) \ No newline at end of file +) diff --git a/ext/intl/tests/timezone_getID_error.phpt b/ext/intl/tests/timezone_getID_error.phpt deleted file mode 100644 index 44b305f464d..00000000000 --- a/ext/intl/tests/timezone_getID_error.phpt +++ /dev/null @@ -1,16 +0,0 @@ ---TEST-- -IntlTimeZone::getID(): errors ---EXTENSIONS-- -intl ---FILE-- - ---EXPECTF-- -Fatal error: Uncaught TypeError: intltz_get_id(): Argument #1 ($timezone) must be of type IntlTimeZone, null given in %s:%d -Stack trace: -#0 %s(%d): intltz_get_id(NULL) -#1 {main} - thrown in %s on line %d diff --git a/ext/intl/tests/timezone_getIanaID.phpt b/ext/intl/tests/timezone_getIanaID.phpt index 7f728e48ec5..1db39c398d6 100644 --- a/ext/intl/tests/timezone_getIanaID.phpt +++ b/ext/intl/tests/timezone_getIanaID.phpt @@ -6,20 +6,24 @@ intl = 74.0'); ?> --FILE-- ---EXPECTF-- -Warning: IntlTimeZone::getIanaID(): could not convert time zone id to UTF-16 in %s on line %d +--EXPECT-- bool(false) - -Warning: IntlTimeZone::getIanaID(): error obtaining IANA ID in %s on line %d +IntlTimeZone::getIanaID(): could not convert time zone id to UTF-16: U_INVALID_CHAR_FOUND bool(false) +IntlTimeZone::getIanaID(): error obtaining IANA ID: U_ILLEGAL_ARGUMENT_ERROR string(13) "Europe/Dublin" +U_ZERO_ERROR string(12) "Asia/Kolkata" +U_ZERO_ERROR bool(true) diff --git a/ext/intl/tests/timezone_getOffset_basic.phpt b/ext/intl/tests/timezone_getOffset_basic.phpt index 2f86869479c..55c2fa7caee 100644 --- a/ext/intl/tests/timezone_getOffset_basic.phpt +++ b/ext/intl/tests/timezone_getOffset_basic.phpt @@ -6,7 +6,6 @@ date.timezone=Atlantic/Azores intl --FILE-- --FILE-- getOffset(INF, true, $a, $a)); +echo intl_get_error_message(), PHP_EOL; -intltz_get_offset(null, time()*1000, false, $a, $a); ?> ---EXPECTF-- -Warning: IntlTimeZone::getOffset(): error obtaining offset in %s on line %d +--EXPECT-- bool(false) - -Fatal error: Uncaught TypeError: intltz_get_offset(): Argument #1 ($timezone) must be of type IntlTimeZone, null given in %s:%d -Stack trace: -#0 %s(%d): intltz_get_offset(NULL, %f, false, NULL, NULL) -#1 {main} - thrown in %s on line %d +IntlTimeZone::getOffset(): error obtaining offset: U_ILLEGAL_ARGUMENT_ERROR diff --git a/ext/intl/tests/timezone_getRawOffset_basic.phpt b/ext/intl/tests/timezone_getRawOffset_basic.phpt index 734df41375c..545f1f1f8d8 100644 --- a/ext/intl/tests/timezone_getRawOffset_basic.phpt +++ b/ext/intl/tests/timezone_getRawOffset_basic.phpt @@ -4,7 +4,6 @@ IntlTimeZone::getRawOffset(): basic test intl --FILE-- getRawOffset()); @@ -14,4 +13,4 @@ var_dump(intltz_get_raw_offset($lsb)); ?> --EXPECT-- int(3600000) -int(0) \ No newline at end of file +int(0) diff --git a/ext/intl/tests/timezone_getRawOffset_error.phpt b/ext/intl/tests/timezone_getRawOffset_error.phpt deleted file mode 100644 index cc508ddbbeb..00000000000 --- a/ext/intl/tests/timezone_getRawOffset_error.phpt +++ /dev/null @@ -1,16 +0,0 @@ ---TEST-- -IntlTimeZone::getRawOffset(): errors ---EXTENSIONS-- -intl ---FILE-- - ---EXPECTF-- -Fatal error: Uncaught TypeError: intltz_get_raw_offset(): Argument #1 ($timezone) must be of type IntlTimeZone, null given in %s:%d -Stack trace: -#0 %s(%d): intltz_get_raw_offset(NULL) -#1 {main} - thrown in %s on line %d diff --git a/ext/intl/tests/timezone_getRegion_basic.phpt b/ext/intl/tests/timezone_getRegion_basic.phpt index 4aecd30e87d..b156cb67455 100644 --- a/ext/intl/tests/timezone_getRegion_basic.phpt +++ b/ext/intl/tests/timezone_getRegion_basic.phpt @@ -4,12 +4,11 @@ IntlTimeZone::getRegion(): basic test intl --FILE-- --EXPECT-- -NL -NL +string(2) "NL" +string(2) "NL" diff --git a/ext/intl/tests/timezone_getRegion_error.phpt b/ext/intl/tests/timezone_getRegion_error.phpt index 70acbaa6fbc..d5ef9f2ae92 100644 --- a/ext/intl/tests/timezone_getRegion_error.phpt +++ b/ext/intl/tests/timezone_getRegion_error.phpt @@ -4,14 +4,15 @@ IntlTimeZone::getRegion(): errors intl --FILE-- ---EXPECTF-- -Warning: IntlTimeZone::getRegion(): could not convert time zone id to UTF-16 in %s on line %d -bool(false) +echo intl_get_error_message(), PHP_EOL; -Warning: IntlTimeZone::getRegion(): error obtaining region in %s on line %d +?> +--EXPECT-- bool(false) +IntlTimeZone::getRegion(): could not convert time zone id to UTF-16: U_INVALID_CHAR_FOUND +bool(false) +IntlTimeZone::getRegion(): error obtaining region: U_ILLEGAL_ARGUMENT_ERROR diff --git a/ext/intl/tests/timezone_getTZData_basic.phpt b/ext/intl/tests/timezone_getTZData_basic.phpt index bf0b3dfb934..99d21357b55 100644 --- a/ext/intl/tests/timezone_getTZData_basic.phpt +++ b/ext/intl/tests/timezone_getTZData_basic.phpt @@ -4,7 +4,6 @@ IntlTimeZone::getTZDataVersion: basic test intl --FILE-- --EXPECTF-- 20%d%s -20%d%s \ No newline at end of file +20%d%s diff --git a/ext/intl/tests/timezone_getUnknown_basic.phpt b/ext/intl/tests/timezone_getUnknown_basic.phpt index a7c2ac58177..71785fc656c 100644 --- a/ext/intl/tests/timezone_getUnknown_basic.phpt +++ b/ext/intl/tests/timezone_getUnknown_basic.phpt @@ -4,7 +4,6 @@ IntlCalendar::getUnknown(): basic test intl --FILE-- hasSameRules('foo')); -} catch (Error $ex) { - var_dump($ex->getCode(), $ex->getMessage()); - echo "\n"; -} - -try { - var_dump(intltz_has_same_rules(null, $tz)); -} catch (Error $ex) { - var_dump($ex->getCode(), $ex->getMessage()); - echo "\n"; -} -?> ---EXPECT-- -int(0) -string(93) "IntlTimeZone::hasSameRules(): Argument #1 ($other) must be of type IntlTimeZone, string given" - -int(0) -string(89) "intltz_has_same_rules(): Argument #1 ($timezone) must be of type IntlTimeZone, null given" diff --git a/ext/intl/tests/timezone_toDateTimeZone_basic.phpt b/ext/intl/tests/timezone_toDateTimeZone_basic.phpt index d82f65d7c0f..bd5f6809d7e 100644 --- a/ext/intl/tests/timezone_toDateTimeZone_basic.phpt +++ b/ext/intl/tests/timezone_toDateTimeZone_basic.phpt @@ -2,11 +2,11 @@ IntlTimeZone::toDateTimeZone(): basic test --EXTENSIONS-- intl +--INI-- +date.timezone=Europe/Lisbon +intl.default_locale=nl --FILE-- getID(), $tz->getRawOffset()); diff --git a/ext/intl/tests/timezone_toDateTimeZone_error.phpt b/ext/intl/tests/timezone_toDateTimeZone_error.phpt index 7355185541b..8ba5be884b4 100644 --- a/ext/intl/tests/timezone_toDateTimeZone_error.phpt +++ b/ext/intl/tests/timezone_toDateTimeZone_error.phpt @@ -4,24 +4,18 @@ IntlTimeZone::toDateTimeZone(): errors intl --FILE-- toDateTimeZone()); -} catch (Exception $e) { - var_dump($e->getMessage()); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; + $previous = $e->getPrevious(); + echo ' ', $previous::class, ': ', $previous->getMessage(), PHP_EOL; } -var_dump(intltz_to_date_time_zone(1)); ?> ---EXPECTF-- -Warning: IntlTimeZone::toDateTimeZone(): intltz_to_date_time_zone: DateTimeZone constructor threw exception in %s on line %d -string(66) "DateTimeZone::__construct(): Unknown or bad timezone (Etc/Unknown)" - -Fatal error: Uncaught TypeError: intltz_to_date_time_zone(): Argument #1 ($timezone) must be of type IntlTimeZone, int given in %s:%d -Stack trace: -#0 %s(%d): intltz_to_date_time_zone(1) -#1 {main} - thrown in %s on line %d +--EXPECT-- +IntlException: DateTimeZone constructor threw exception + DateInvalidTimeZoneException: DateTimeZone::__construct(): Unknown or bad timezone (Etc/Unknown) diff --git a/ext/intl/tests/timezone_useDaylightTime_basic.phpt b/ext/intl/tests/timezone_useDaylightTime_basic.phpt index 2f8d02c2d15..3451739bb70 100644 --- a/ext/intl/tests/timezone_useDaylightTime_basic.phpt +++ b/ext/intl/tests/timezone_useDaylightTime_basic.phpt @@ -4,7 +4,6 @@ IntlTimeZone::useDaylightTime: basic test intl --FILE-- ---EXPECTF-- -Fatal error: Uncaught TypeError: intltz_use_daylight_time(): Argument #1 ($timezone) must be of type IntlTimeZone, null given in %s:%d -Stack trace: -#0 %s(%d): intltz_use_daylight_time(NULL) -#1 {main} - thrown in %s on line %d diff --git a/ext/intl/tests/timezone_windowsID_basic2.phpt b/ext/intl/tests/timezone_windowsID_basic2.phpt index aa1ce7f886c..0db032207fa 100644 --- a/ext/intl/tests/timezone_windowsID_basic2.phpt +++ b/ext/intl/tests/timezone_windowsID_basic2.phpt @@ -33,7 +33,7 @@ string(18) "Cuba Standard Time" string(21) "Central Standard Time" string(21) "Pacific Standard Time" bool(false) -Error: unknown system timezone: U_ILLEGAL_ARGUMENT_ERROR +Error: IntlTimeZone::getWindowsID(): unknown system timezone: U_ILLEGAL_ARGUMENT_ERROR string(21) "Morocco Standard Time" string(23) "Singapore Standard Time" string(26) "W. Australia Standard Time" diff --git a/ext/intl/tests/transliterator_clone.phpt b/ext/intl/tests/transliterator_clone.phpt index 057e2a7aef4..ccbe56ea6af 100644 --- a/ext/intl/tests/transliterator_clone.phpt +++ b/ext/intl/tests/transliterator_clone.phpt @@ -4,7 +4,6 @@ Transliterator clone handler intl --FILE-- id,"\n"; diff --git a/ext/intl/tests/transliterator_create_error.phpt b/ext/intl/tests/transliterator_create_error.phpt index b554fb0dce5..fd7db47a42e 100644 --- a/ext/intl/tests/transliterator_create_error.phpt +++ b/ext/intl/tests/transliterator_create_error.phpt @@ -5,18 +5,14 @@ intl --FILE-- ---EXPECTF-- -Warning: Transliterator::create(): transliterator_create: unable to open ICU transliterator with id "inexistent id" in %s on line %d -transliterator_create: unable to open ICU transliterator with id "inexistent id": U_INVALID_ID - -Warning: Transliterator::create(): String conversion of id to UTF-16 failed in %s on line %d -String conversion of id to UTF-16 failed: U_INVALID_CHAR_FOUND -Done. +--EXPECT-- +NULL +Transliterator::create(): unable to open ICU transliterator with id "inexistent id": U_INVALID_ID +NULL +Transliterator::create(): String conversion of id to UTF-16 failed: U_INVALID_CHAR_FOUND diff --git a/ext/intl/tests/transliterator_create_from_rule_basic.phpt b/ext/intl/tests/transliterator_create_from_rule_basic.phpt index 5c9aa182b52..02f0b0362b7 100644 --- a/ext/intl/tests/transliterator_create_from_rule_basic.phpt +++ b/ext/intl/tests/transliterator_create_from_rule_basic.phpt @@ -4,7 +4,6 @@ Transliterator::createFromRules (basic) intl --FILE-- y; diff --git a/ext/intl/tests/transliterator_create_from_rule_error.phpt b/ext/intl/tests/transliterator_create_from_rule_error.phpt index 9a3b86944c8..e6f885bfbc8 100644 --- a/ext/intl/tests/transliterator_create_from_rule_error.phpt +++ b/ext/intl/tests/transliterator_create_from_rule_error.phpt @@ -4,7 +4,6 @@ Transliterator::createFromRules (error) intl --FILE-- ---EXPECTF-- -Warning: Transliterator::createFromRules(): String conversion of rules to UTF-16 failed in %s on line %d -String conversion of rules to UTF-16 failed: U_INVALID_CHAR_FOUND - -Warning: Transliterator::createFromRules(): transliterator_create_from_rules: unable to create ICU transliterator from rules (parse error after "{'``'}a > “;", before or at "{'``'}a > b;") in %s on line %d -transliterator_create_from_rules: unable to create ICU transliterator from rules (parse error after "{'``'}a > “;", before or at "{'``'}a > b;"): U_RULE_MASK_ERROR - -Warning: Transliterator::createFromRules(): transliterator_create_from_rules: unable to create ICU transliterator from rules (parse error at offset 0, before or at "ffff") in %s on line %d -transliterator_create_from_rules: unable to create ICU transliterator from rules (parse error at offset 0, before or at "ffff"): U_MISSING_OPERATOR +--EXPECT-- +Transliterator::createFromRules(): String conversion of rules to UTF-16 failed: U_INVALID_CHAR_FOUND +Transliterator::createFromRules(): unable to create ICU transliterator from rules (parse error after "{'``'}a > “;", before or at "{'``'}a > b;"): U_RULE_MASK_ERROR +Transliterator::createFromRules(): unable to create ICU transliterator from rules (parse error at offset 0, before or at "ffff"): U_MISSING_OPERATOR Done. diff --git a/ext/intl/tests/transliterator_create_inverse_basic.phpt b/ext/intl/tests/transliterator_create_inverse_basic.phpt index 7206d61ea07..ed9187b4c04 100644 --- a/ext/intl/tests/transliterator_create_inverse_basic.phpt +++ b/ext/intl/tests/transliterator_create_inverse_basic.phpt @@ -5,8 +5,6 @@ intl --FILE-- transliterate($orstr); diff --git a/ext/intl/tests/transliterator_create_inverse_error.phpt b/ext/intl/tests/transliterator_create_inverse_error.phpt deleted file mode 100644 index a229a2eb790..00000000000 --- a/ext/intl/tests/transliterator_create_inverse_error.phpt +++ /dev/null @@ -1,17 +0,0 @@ ---TEST-- -Transliterator::createInverse (error) ---EXTENSIONS-- -intl ---FILE-- - ---EXPECTF-- -Fatal error: Uncaught TypeError: transliterator_create_inverse(): Argument #1 ($transliterator) must be of type Transliterator, string given in %s:%d -Stack trace: -#0 %s(%d): transliterator_create_inverse('jj') -#1 {main} - thrown in %s on line %d diff --git a/ext/intl/tests/transliterator_get_error_code_basic.phpt b/ext/intl/tests/transliterator_get_error_code_basic.phpt deleted file mode 100644 index 8fb59aa8b87..00000000000 --- a/ext/intl/tests/transliterator_get_error_code_basic.phpt +++ /dev/null @@ -1,26 +0,0 @@ ---TEST-- -Transliterator::getErrorCode (basic) ---EXTENSIONS-- -intl ---FILE-- -transliterate("\x8F")); -echo transliterator_get_error_code($t), "\n"; - -echo $t->getErrorCode(), "\n"; - -var_dump($t->transliterate("")); -echo $t->getErrorCode(), "\n"; - -echo "Done.\n"; -?> ---EXPECTF-- -Warning: Transliterator::transliterate(): String conversion of string to UTF-16 failed in %s on line %d -bool(false) -10 -10 -string(0) "" -0 -Done. diff --git a/ext/intl/tests/transliterator_get_error_code_error.phpt b/ext/intl/tests/transliterator_get_error_code_error.phpt deleted file mode 100644 index bb90e4ab6a4..00000000000 --- a/ext/intl/tests/transliterator_get_error_code_error.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---TEST-- -Transliterator::getErrorCode (error) ---EXTENSIONS-- -intl ---FILE-- - ---EXPECTF-- -Fatal error: Uncaught TypeError: transliterator_get_error_code(): Argument #1 ($transliterator) must be of type Transliterator, array given in %s:%d -Stack trace: -#0 %s(%d): transliterator_get_error_code(Array) -#1 {main} - thrown in %s on line %d diff --git a/ext/intl/tests/transliterator_get_error_message_basic.phpt b/ext/intl/tests/transliterator_get_error_message_basic.phpt index 3c4c9eca513..6f5ae0e4d0e 100644 --- a/ext/intl/tests/transliterator_get_error_message_basic.phpt +++ b/ext/intl/tests/transliterator_get_error_message_basic.phpt @@ -1,26 +1,23 @@ --TEST-- -Transliterator::getErrorMessage (basic) +Transliterator::getErrorMessage() and Transliterator::getErrorCode()(basic) --EXTENSIONS-- intl --FILE-- transliterate("\x8F")); -echo transliterator_get_error_message($t), "\n"; -echo $t->getErrorMessage(), "\n"; +echo transliterator_get_error_code($t), ': ', transliterator_get_error_message($t), "\n"; + +echo $t->getErrorCode(), ': ', $t->getErrorMessage(), "\n"; var_dump($t->transliterate("")); -echo $t->getErrorMessage(), "\n"; +echo $t->getErrorCode(), ': ', $t->getErrorMessage(), "\n"; -echo "Done.\n"; ?> ---EXPECTF-- -Warning: Transliterator::transliterate(): String conversion of string to UTF-16 failed in %s on line %d +--EXPECT-- bool(false) -String conversion of string to UTF-16 failed: U_INVALID_CHAR_FOUND -String conversion of string to UTF-16 failed: U_INVALID_CHAR_FOUND +10: Transliterator::transliterate(): String conversion of string to UTF-16 failed: U_INVALID_CHAR_FOUND +10: Transliterator::transliterate(): String conversion of string to UTF-16 failed: U_INVALID_CHAR_FOUND string(0) "" -U_ZERO_ERROR -Done. +0: U_ZERO_ERROR diff --git a/ext/intl/tests/transliterator_get_error_message_error.phpt b/ext/intl/tests/transliterator_get_error_message_error.phpt deleted file mode 100644 index 8449c3671d4..00000000000 --- a/ext/intl/tests/transliterator_get_error_message_error.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---TEST-- -Transliterator::getErrorMessage (error) ---EXTENSIONS-- -intl ---FILE-- - ---EXPECTF-- -Fatal error: Uncaught TypeError: transliterator_get_error_message(): Argument #1 ($transliterator) must be of type Transliterator, array given in %s:%d -Stack trace: -#0 %s(%d): transliterator_get_error_message(Array) -#1 {main} - thrown in %s on line %d diff --git a/ext/intl/tests/transliterator_list_ids_basic.phpt b/ext/intl/tests/transliterator_list_ids_basic.phpt index f6ffb06e81d..8a808cd6945 100644 --- a/ext/intl/tests/transliterator_list_ids_basic.phpt +++ b/ext/intl/tests/transliterator_list_ids_basic.phpt @@ -5,7 +5,6 @@ intl --FILE-- 100); var_dump(count(Transliterator::listIDs()) > 100); diff --git a/ext/intl/tests/transliterator_transliterate_error.phpt b/ext/intl/tests/transliterator_transliterate_error.phpt index 4a354465bf2..e11de9333d4 100644 --- a/ext/intl/tests/transliterator_transliterate_error.phpt +++ b/ext/intl/tests/transliterator_transliterate_error.phpt @@ -2,31 +2,34 @@ Transliterator::transliterate (error) --EXTENSIONS-- intl +--INI-- +intl.use_exceptions=true --FILE-- getMessage(), PHP_EOL; +} try { - transliterator_transliterate($tr,"str",7,6); -} catch (ValueError $exception) { - echo $exception->getMessage() . "\n"; + transliterator_transliterate($tr, "str", 7, 6); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; } //bad UTF-8 -transliterator_transliterate($tr, "\x80\x03"); +try { + transliterator_transliterate($tr, "\x80\x03"); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; +} -echo "Done.\n"; ?> ---EXPECTF-- -Warning: transliterator_transliterate(): transliterator_transliterate: Neither "start" nor the "end" arguments can exceed the number of UTF-16 code units (in this case, 3) in %s on line %d -bool(false) -transliterator_transliterate(): Argument #2 ($string) must be less than or equal to argument #3 ($end) - -Warning: transliterator_transliterate(): String conversion of string to UTF-16 failed in %s on line %d -Done. +--EXPECT-- +IntlException: transliterator_transliterate(): Neither "start" nor the "end" arguments can exceed the number of UTF-16 code units (in this case, 3) +ValueError: transliterator_transliterate(): Argument #2 ($string) must be less than or equal to argument #3 ($end) +IntlException: transliterator_transliterate(): String conversion of string to UTF-16 failed diff --git a/ext/intl/tests/transliterator_transliterate_variant1.phpt b/ext/intl/tests/transliterator_transliterate_variant1.phpt index 0e288ee63d2..1cc76cd244a 100644 --- a/ext/intl/tests/transliterator_transliterate_variant1.phpt +++ b/ext/intl/tests/transliterator_transliterate_variant1.phpt @@ -2,37 +2,32 @@ transliterator_transliterate (variant 1, non-transliterator 1st arg) --EXTENSIONS-- intl +--INI-- +intl.use_exceptions=true --FILE-- getMessage(), PHP_EOL; } -echo transliterator_transliterate(new A(), $str), "\n"; -echo intl_get_error_message(), "\n"; +class A { + function __toString() { return "inexistent id"; } +} -echo "Done.\n"; +try { + echo transliterator_transliterate(new A(), $str), "\n"; +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; +} ?> ---EXPECTF-- +--EXPECT-- \u0020o - -Warning: transliterator_transliterate(): String conversion of id to UTF-16 failed in %s on line %d - -Warning: transliterator_transliterate(): Could not create transliterator with ID %s - -String conversion of id to UTF-16 failed: U_INVALID_CHAR_FOUND - -Warning: transliterator_transliterate(): transliterator_create: unable to open ICU transliterator with id "inexistent id" in %s on line %d - -Warning: transliterator_transliterate(): Could not create transliterator with ID "inexistent id" (transliterator_create: unable to open ICU transliterator with id "inexistent id": U_INVALID_ID) in %s on line %d - -transliterator_create: unable to open ICU transliterator with id "inexistent id": U_INVALID_ID -Done. +IntlException: transliterator_transliterate(): String conversion of id to UTF-16 failed +IntlException: transliterator_transliterate(): unable to open ICU transliterator with id "inexistent id" diff --git a/ext/intl/tests/uconverter___construct_error.phpt b/ext/intl/tests/uconverter___construct_error.phpt index 92adc4a7186..7237f799f88 100644 --- a/ext/intl/tests/uconverter___construct_error.phpt +++ b/ext/intl/tests/uconverter___construct_error.phpt @@ -1,15 +1,22 @@ --TEST-- Basic UConverter::convert() usage ---INI-- -intl.error_level = E_WARNING --EXTENSIONS-- intl --FILE-- ---EXPECTF-- -Warning: UConverter::__construct(): ucnv_open() returned error 4: U_FILE_ACCESS_ERROR in %s on line %d -object(UConverter)#%d (0) { +try { + $c = new UConverter("\x80", 'utf-8'); + var_dump($c); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; } +try { + $c = new UConverter('utf-8', "\x80"); + var_dump($c); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; +} +?> +--EXPECT-- +IntlException: UConverter::__construct(): returned error 4: U_FILE_ACCESS_ERROR +IntlException: UConverter::__construct(): returned error 4: U_FILE_ACCESS_ERROR diff --git a/ext/intl/tests/uconverter_bug66873.phpt b/ext/intl/tests/uconverter_bug66873.phpt index 9ea684fbd38..68a01eee93d 100644 --- a/ext/intl/tests/uconverter_bug66873.phpt +++ b/ext/intl/tests/uconverter_bug66873.phpt @@ -4,9 +4,13 @@ Bug #66873 - crash in UConverter with invalid encoding intl --FILE-- toUCallback(1, 1, 1, $b); var_dump($o->getErrorCode()); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; +} ?> --EXPECT-- -int(27) +IntlException: UConverter::__construct(): returned error 4: U_FILE_ACCESS_ERROR diff --git a/ext/intl/tests/uconverter_func_subst.phpt b/ext/intl/tests/uconverter_func_subst.phpt index f8a32e814bb..8d6553fc983 100644 --- a/ext/intl/tests/uconverter_func_subst.phpt +++ b/ext/intl/tests/uconverter_func_subst.phpt @@ -1,5 +1,5 @@ --TEST-- -Basic UConverter::convert() w/ Subsitution +Basic UConverter::convert() w/ Substitution --EXTENSIONS-- intl --INI-- @@ -25,7 +25,7 @@ foreach(array('?','','??') as $subst) { --EXPECT-- string(23) "This is an ascii string" string(12) "Snowman: (?)" -Error: transcode() returned error 1: U_ILLEGAL_ARGUMENT_ERROR: U_ILLEGAL_ARGUMENT_ERROR -Error: transcode() returned error 1: U_ILLEGAL_ARGUMENT_ERROR: U_ILLEGAL_ARGUMENT_ERROR -Error: transcode() returned error 1: U_ILLEGAL_ARGUMENT_ERROR: U_ILLEGAL_ARGUMENT_ERROR -Error: transcode() returned error 1: U_ILLEGAL_ARGUMENT_ERROR: U_ILLEGAL_ARGUMENT_ERROR +Error: UConverter::transcode(): returned error 1: U_ILLEGAL_ARGUMENT_ERROR: U_ILLEGAL_ARGUMENT_ERROR +Error: UConverter::transcode(): returned error 1: U_ILLEGAL_ARGUMENT_ERROR: U_ILLEGAL_ARGUMENT_ERROR +Error: UConverter::transcode(): returned error 1: U_ILLEGAL_ARGUMENT_ERROR: U_ILLEGAL_ARGUMENT_ERROR +Error: UConverter::transcode(): returned error 1: U_ILLEGAL_ARGUMENT_ERROR: U_ILLEGAL_ARGUMENT_ERROR diff --git a/ext/intl/tests/uconverter_getDestinationEncoding.phpt b/ext/intl/tests/uconverter_getDestinationEncoding.phpt index d354f2a5682..ca1a9b4d5a4 100644 --- a/ext/intl/tests/uconverter_getDestinationEncoding.phpt +++ b/ext/intl/tests/uconverter_getDestinationEncoding.phpt @@ -2,8 +2,6 @@ UConverter::getDestinationEncoding() --CREDITS-- Andy McNeice - PHP Testfest 2017 ---INI-- -intl.error_level = E_WARNING --EXTENSIONS-- intl --FILE-- diff --git a/ext/intl/tests/uconverter_getSourceEncoding.phpt b/ext/intl/tests/uconverter_getSourceEncoding.phpt index 1bd99f81de0..2065f83e9b5 100644 --- a/ext/intl/tests/uconverter_getSourceEncoding.phpt +++ b/ext/intl/tests/uconverter_getSourceEncoding.phpt @@ -2,8 +2,6 @@ UConverter::getSourceEncoding() --CREDITS-- Andy McNeice - PHP Testfest 2017 ---INI-- -intl.error_level = E_WARNING --EXTENSIONS-- intl --FILE-- diff --git a/ext/intl/tests/uconverter_setSourceEncoding.phpt b/ext/intl/tests/uconverter_setSourceEncoding.phpt index 3ad539bf80b..c29558d546a 100644 --- a/ext/intl/tests/uconverter_setSourceEncoding.phpt +++ b/ext/intl/tests/uconverter_setSourceEncoding.phpt @@ -2,8 +2,6 @@ UConverter::setSourceEncoding() --CREDITS-- Andy McNeice - PHP Testfest 2017 ---INI-- -intl.error_level = E_WARNING --EXTENSIONS-- intl --FILE-- diff --git a/ext/intl/timezone/timezone.stub.php b/ext/intl/timezone/timezone.stub.php index c879bb9ce55..8a8927f7cd8 100644 --- a/ext/intl/timezone/timezone.stub.php +++ b/ext/intl/timezone/timezone.stub.php @@ -45,11 +45,10 @@ class IntlTimeZone public static function createDefault(): IntlTimeZone {} /** - * @param IntlTimeZone|string|int|float|null $countryOrRawOffset * @tentative-return-type * @alias intltz_create_enumeration */ - public static function createEnumeration($countryOrRawOffset = null): IntlIterator|false {} + public static function createEnumeration(string|int|null $countryOrRawOffset = null): IntlIterator|false {} /** * @tentative-return-type diff --git a/ext/intl/timezone/timezone_arginfo.h b/ext/intl/timezone/timezone_arginfo.h index 6206e03efad..e30e9806d9d 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: 6ffeea8491aa48c49879fa77bdb644d10d5c71bd */ + * Stub hash: 22e652c6a05ade0a6fd3119e4742cd260ba27146 */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_IntlTimeZone___construct, 0, 0, 0) ZEND_END_ARG_INFO() @@ -12,7 +12,7 @@ ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_INFO_EX(arginfo_class_IntlTimeZone_crea ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_IntlTimeZone_createEnumeration, 0, 0, IntlIterator, MAY_BE_FALSE) - ZEND_ARG_INFO_WITH_DEFAULT_VALUE(0, countryOrRawOffset, "null") + ZEND_ARG_TYPE_MASK(0, countryOrRawOffset, MAY_BE_STRING|MAY_BE_LONG|MAY_BE_NULL, "null") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_INFO_EX(arginfo_class_IntlTimeZone_createTimeZone, 0, 1, IntlTimeZone, 1) diff --git a/ext/intl/timezone/timezone_class.cpp b/ext/intl/timezone/timezone_class.cpp index 2617b59a11b..c613edf5585 100644 --- a/ext/intl/timezone/timezone_class.cpp +++ b/ext/intl/timezone/timezone_class.cpp @@ -18,6 +18,7 @@ #endif #include "../intl_cppshims.h" +#include #include #include @@ -61,144 +62,144 @@ U_CFUNC void timezone_object_construct(const TimeZone *zone, zval *object, int o * Convert from TimeZone to DateTimeZone object */ U_CFUNC zval *timezone_convert_to_datetimezone(const TimeZone *timeZone, intl_error *outside_error, - const char *func, zval *ret) + zval *ret) { - UnicodeString id; - char *message = NULL; - php_timezone_obj *tzobj; - zval arg; + UnicodeString id; timeZone->getID(id); if (id.isBogus()) { - spprintf(&message, 0, "%s: could not obtain TimeZone id", func); intl_errors_set(outside_error, U_ILLEGAL_ARGUMENT_ERROR, - message, 1); - goto error; + "could not obtain TimeZone id"); + return nullptr; } - object_init_ex(ret, php_date_get_timezone_ce()); - tzobj = Z_PHPTIMEZONE_P(ret); - if (id.compare(0, 3, UnicodeString("GMT", sizeof("GMT")-1, US_INV)) == 0) { /* The DateTimeZone constructor doesn't support offset time zones, - * so we must mess with DateTimeZone structure ourselves */ - tzobj->initialized = 1; + * so we must mess with DateTimeZone structure ourselves */ + object_init_ex(ret, php_date_get_timezone_ce()); + php_timezone_obj *tzobj = Z_PHPTIMEZONE_P(ret); + + tzobj->initialized = true; tzobj->type = TIMELIB_ZONETYPE_OFFSET; //convert offset from milliseconds to seconds tzobj->tzi.utc_offset = timeZone->getRawOffset() / 1000; } else { - zend_string *u8str; - /* Call the constructor! */ - u8str = intl_charFromString(id, &INTL_ERROR_CODE(*outside_error)); + zend_string *u8str = intl_charFromString(id, &INTL_ERROR_CODE(*outside_error)); if (!u8str) { - spprintf(&message, 0, "%s: could not convert id to UTF-8", func); intl_errors_set(outside_error, INTL_ERROR_CODE(*outside_error), - message, 1); - goto error; + "could not convert id to UTF-8"); + return nullptr; } + + zval arg; ZVAL_STR(&arg, u8str); - zend_call_known_instance_method_with_1_params( - Z_OBJCE_P(ret)->constructor, Z_OBJ_P(ret), NULL, &arg); - if (EG(exception)) { - spprintf(&message, 0, - "%s: DateTimeZone constructor threw exception", func); - intl_errors_set(outside_error, U_ILLEGAL_ARGUMENT_ERROR, - message, 1); - zend_object_store_ctor_failed(Z_OBJ_P(ret)); - zval_ptr_dtor(&arg); - goto error; - } + /* Instantiate the object and call the constructor */ + zend_result status = object_init_with_constructor(ret, php_date_get_timezone_ce(), 1, &arg, nullptr); zval_ptr_dtor(&arg); - } - - if (0) { -error: - if (ret) { - zval_ptr_dtor(ret); + if (UNEXPECTED(status == FAILURE)) { + zend_throw_exception(IntlException_ce_ptr, "DateTimeZone constructor threw exception", 0); + return nullptr; } - ret = NULL; } - if (message) { - efree(message); - } return ret; } /* }}} */ -/* {{{ timezone_process_timezone_argument - * TimeZone argument processor. outside_error may be NULL (for static functions/constructors) */ -U_CFUNC TimeZone *timezone_process_timezone_argument(zval *zv_timezone, - intl_error *outside_error, - const char *func) +static void timezone_throw_exception_with_call_location(const char *msg, const char *add_info) { - zval local_zv_tz; - TimeZone *timeZone; + zend_string *fn = get_active_function_or_method_name(); + zend_throw_error(IntlException_ce_ptr, "%s(): %s%s%s%s", + ZSTR_VAL(fn), msg, + add_info ? "\"" : "", + add_info ? add_info : "", + add_info ? "\"" : "" + ); + zend_string_release_ex(fn, false); +} - if (zv_timezone == NULL || Z_TYPE_P(zv_timezone) == IS_NULL) { +/* {{{ timezone_process_timezone_argument + * TimeZone argument processor. outside_error may be nullptr (for static functions/constructors) */ +U_CFUNC TimeZone *timezone_process_timezone_argument( + zend_object *timezone_object, zend_string *timezone_string, intl_error *outside_error) +{ + std::unique_ptr timeZone; + bool free_string = false; + + if (timezone_object == nullptr && timezone_string == nullptr) { timelib_tzinfo *tzinfo = get_timezone_info(); - ZVAL_STRING(&local_zv_tz, tzinfo->name); - zv_timezone = &local_zv_tz; - } else { - ZVAL_NULL(&local_zv_tz); + timezone_string = zend_string_init(tzinfo->name, strlen(tzinfo->name), false); + free_string = true; } - if (Z_TYPE_P(zv_timezone) == IS_OBJECT && - instanceof_function(Z_OBJCE_P(zv_timezone), TimeZone_ce_ptr)) { - TimeZone_object *to = Z_INTL_TIMEZONE_P(zv_timezone); + if (timezone_object != nullptr) { + if (instanceof_function(timezone_object->ce, TimeZone_ce_ptr)) { + const TimeZone_object *to = php_intl_timezone_fetch_object(timezone_object); - if (to->utimezone == NULL) { - zend_throw_error(IntlException_ce_ptr, "%s: passed IntlTimeZone is not " - "properly constructed", func); - zval_ptr_dtor_str(&local_zv_tz); - return NULL; - } - timeZone = to->utimezone->clone(); - if (UNEXPECTED(timeZone == NULL)) { - zend_throw_error(IntlException_ce_ptr, "%s: could not clone TimeZone", func); - zval_ptr_dtor_str(&local_zv_tz); - return NULL; - } - } else if (Z_TYPE_P(zv_timezone) == IS_OBJECT && - instanceof_function(Z_OBJCE_P(zv_timezone), php_date_get_timezone_ce())) { + if (UNEXPECTED(to->utimezone == nullptr)) { + timezone_throw_exception_with_call_location( + "passed IntlTimeZone is not properly constructed",nullptr); + return nullptr; + } + timeZone = std::unique_ptr(to->utimezone->clone()); + if (UNEXPECTED(timeZone == nullptr)) { + timezone_throw_exception_with_call_location("could not clone TimeZone", nullptr); + return nullptr; + } + // well, this is included by the centralized C intl part so the "smart" part can't go further + return timeZone.release(); + } else if (instanceof_function(timezone_object->ce, php_date_get_timezone_ce())) { + php_timezone_obj *tz_obj = php_timezone_obj_from_obj(timezone_object); - php_timezone_obj *tzobj = Z_PHPTIMEZONE_P(zv_timezone); - - zval_ptr_dtor_str(&local_zv_tz); - return timezone_convert_datetimezone(tzobj->type, tzobj, 0, - outside_error, func); - } else { - UnicodeString id; - UErrorCode status = U_ZERO_ERROR; /* outside_error may be NULL */ - if (!try_convert_to_string(zv_timezone)) { - zval_ptr_dtor_str(&local_zv_tz); - return NULL; - } - if (intl_stringFromChar(id, Z_STRVAL_P(zv_timezone), Z_STRLEN_P(zv_timezone), - &status) == FAILURE) { - zend_throw_error(IntlException_ce_ptr, "%s: Time zone identifier given is not a " - "valid UTF-8 string", func); - zval_ptr_dtor_str(&local_zv_tz); - return NULL; - } - timeZone = TimeZone::createTimeZone(id); - if (UNEXPECTED(timeZone == NULL)) { - zend_throw_error(IntlException_ce_ptr, "%s: Could not create time zone", func); - zval_ptr_dtor_str(&local_zv_tz); - return NULL; - } - if (*timeZone == TimeZone::getUnknown()) { - zend_throw_error(IntlException_ce_ptr, "%s: No such time zone: '%s'", - func, Z_STRVAL_P(zv_timezone)); - zval_ptr_dtor_str(&local_zv_tz); - delete timeZone; - return NULL; + return timezone_convert_datetimezone(tz_obj->type, tz_obj, false, outside_error); + } else { + zval tmp; + zend_result status = timezone_object->handlers->cast_object(timezone_object, &tmp, IS_STRING); + if (EXPECTED(status == SUCCESS)) { + timezone_string = Z_STR(tmp); + free_string = true; + } else { + if (!EG(exception)) { + // TODO Proper type error + zend_throw_error(nullptr, "Object of class %s could not be converted to string", ZSTR_VAL(timezone_object->ce->name)); + } + return nullptr; + } } } - zval_ptr_dtor_str(&local_zv_tz); + ZEND_ASSERT(timezone_string != nullptr); + UnicodeString id; + UErrorCode status = U_ZERO_ERROR; /* outside_error may be nullptr */ - return timeZone; + if (UNEXPECTED(intl_stringFromChar(id, ZSTR_VAL(timezone_string), ZSTR_LEN(timezone_string), &status) == FAILURE)) { + timezone_throw_exception_with_call_location("Time zone identifier given is not a valid UTF-8 string", nullptr); + if (free_string) { + zend_string_release_ex(timezone_string, false); + } + return nullptr; + } + + timeZone = std::unique_ptr(TimeZone::createTimeZone(id)); + if (UNEXPECTED(timeZone == nullptr)) { + timezone_throw_exception_with_call_location("Could not create time zone",nullptr); + if (free_string) { + zend_string_release_ex(timezone_string, false); + } + return nullptr; + } + if (UNEXPECTED(*timeZone == TimeZone::getUnknown())) { + timezone_throw_exception_with_call_location("No such time zone: ", ZSTR_VAL(timezone_string)); + if (free_string) { + zend_string_release_ex(timezone_string, false); + } + return nullptr; + } + if (free_string) { + zend_string_release_ex(timezone_string, false); + } + // well, this is included by the centralized C intl part so the "smart" part can't go further + return timeZone.release(); } /* }}} */ diff --git a/ext/intl/timezone/timezone_class.h b/ext/intl/timezone/timezone_class.h index 16d56b9af12..bbfd8adcae2 100644 --- a/ext/intl/timezone/timezone_class.h +++ b/ext/intl/timezone/timezone_class.h @@ -36,6 +36,8 @@ typedef struct { intl_error err; // ICU TimeZone + // TODO?: a direct change isn't possible due to C inclusion (also it s a const) + // but see later it can be made possible through different ICU class usages const TimeZone *utimezone; //whether to delete the timezone on object free @@ -64,8 +66,8 @@ static inline TimeZone_object *php_intl_timezone_fetch_object(zend_object *obj) RETURN_THROWS(); \ } -zval *timezone_convert_to_datetimezone(const TimeZone *timeZone, intl_error *outside_error, const char *func, zval *ret); -TimeZone *timezone_process_timezone_argument(zval *zv_timezone, intl_error *error, const char *func); +zval *timezone_convert_to_datetimezone(const TimeZone *timeZone, intl_error *outside_error, zval *ret); +TimeZone *timezone_process_timezone_argument(zend_object *timezone_object, zend_string *timezone_string, intl_error *error); void timezone_object_construct(const TimeZone *zone, zval *object, int owned); diff --git a/ext/intl/timezone/timezone_methods.cpp b/ext/intl/timezone/timezone_methods.cpp index 6ff0cf51377..3de186a9ca0 100644 --- a/ext/intl/timezone/timezone_methods.cpp +++ b/ext/intl/timezone/timezone_methods.cpp @@ -60,7 +60,7 @@ U_CFUNC PHP_FUNCTION(intltz_create_time_zone) UnicodeString id = UnicodeString(); if (intl_stringFromChar(id, str_id, str_id_len, &status) == FAILURE) { intl_error_set(NULL, status, - "could not convert time zone id to UTF-16", 0); + "could not convert time zone id to UTF-16"); RETURN_NULL(); } @@ -82,14 +82,11 @@ U_CFUNC PHP_FUNCTION(intltz_from_date_time_zone) tzobj = Z_PHPTIMEZONE_P(zv_timezone); if (!tzobj->initialized) { - intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, - "DateTimeZone object is unconstructed", - 0); - RETURN_NULL(); + zend_throw_error(NULL, "DateTimeZone object is unconstructed"); + RETURN_THROWS(); } - tz = timezone_convert_datetimezone(tzobj->type, tzobj, false, NULL, - "intltz_from_date_time_zone"); + tz = timezone_convert_datetimezone(tzobj->type, tzobj, false, NULL); if (tz == NULL) { RETURN_NULL(); } @@ -127,62 +124,36 @@ U_CFUNC PHP_FUNCTION(intltz_get_unknown) U_CFUNC PHP_FUNCTION(intltz_create_enumeration) { - zval *arg = NULL; - StringEnumeration *se = NULL; - intl_error_reset(NULL); + zend_string *timezone = nullptr; + zend_long timezone_shift = 0; + bool is_null = true; + StringEnumeration *se = nullptr; + intl_error_reset(nullptr); /* double indirection to have the zend engine destroy the new zval that * results from separation */ ZEND_PARSE_PARAMETERS_START(0, 1) Z_PARAM_OPTIONAL - Z_PARAM_ZVAL(arg) + Z_PARAM_STR_OR_LONG_OR_NULL(timezone, timezone_shift, is_null) ZEND_PARSE_PARAMETERS_END(); - if (arg == NULL || Z_TYPE_P(arg) == IS_NULL) { + if (is_null) { se = TimeZone::createEnumeration(); - } else if (Z_TYPE_P(arg) == IS_LONG) { -int_offset: - if (UNEXPECTED(Z_LVAL_P(arg) < (zend_long)INT32_MIN || - Z_LVAL_P(arg) > (zend_long)INT32_MAX)) { - intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, - "value is out of range", 0); - RETURN_FALSE; - } else { - se = TimeZone::createEnumeration((int32_t) Z_LVAL_P(arg)); - } - } else if (Z_TYPE_P(arg) == IS_DOUBLE) { -double_offset: - convert_to_long(arg); - goto int_offset; - } else if (Z_TYPE_P(arg) == IS_OBJECT || Z_TYPE_P(arg) == IS_STRING) { - zend_long lval; - double dval; - if (!try_convert_to_string(arg)) { + } else if (timezone != nullptr) { + se = TimeZone::createEnumeration(ZSTR_VAL(timezone)); + } else { + if (UNEXPECTED(ZEND_LONG_EXCEEDS_INT(timezone_shift))) { + zend_argument_value_error(1, "must be between %d and %d", INT32_MIN, INT32_MAX); RETURN_THROWS(); } - switch (is_numeric_string(Z_STRVAL_P(arg), Z_STRLEN_P(arg), &lval, &dval, 0)) { - case IS_DOUBLE: - zval_ptr_dtor(arg); - ZVAL_DOUBLE(arg, dval); - goto double_offset; - case IS_LONG: - zval_ptr_dtor(arg); - ZVAL_LONG(arg, lval); - goto int_offset; - } - /* else call string version */ - se = TimeZone::createEnumeration(Z_STRVAL_P(arg)); - } else { - intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, - "invalid argument type", 0); - RETURN_FALSE; + se = TimeZone::createEnumeration(static_cast(timezone_shift)); } if (se) { IntlIterator_from_StringEnumeration(se, return_value); } else { - intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, - "error obtaining enumeration", 0); + intl_error_set(nullptr, U_ILLEGAL_ARGUMENT_ERROR, + "error obtaining enumeration"); RETVAL_FALSE; } } @@ -201,7 +172,7 @@ U_CFUNC PHP_FUNCTION(intltz_count_equivalent_ids) UnicodeString id = UnicodeString(); if (intl_stringFromChar(id, str_id, str_id_len, &status) == FAILURE) { intl_error_set(NULL, status, - "could not convert time zone id to UTF-16", 0); + "could not convert time zone id to UTF-16"); RETURN_FALSE; } @@ -230,18 +201,17 @@ U_CFUNC PHP_FUNCTION(intltz_create_time_zone_id_enumeration) if (zoneType != UCAL_ZONE_TYPE_ANY && zoneType != UCAL_ZONE_TYPE_CANONICAL && zoneType != UCAL_ZONE_TYPE_CANONICAL_LOCATION) { - intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, - "bad zone type", 0); - RETURN_FALSE; + zend_argument_value_error(1, "must be one of IntlTimeZone::TYPE_ANY," + " IntlTimeZone::TYPE_CANONICAL, or IntlTimeZone::TYPE_CANONICAL_LOCATION"); + RETURN_THROWS(); } if (!arg3isnull) { - if (UNEXPECTED(offset_arg < (zend_long)INT32_MIN || offset_arg > (zend_long)INT32_MAX)) { - intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, - "offset out of bounds", 0); - RETURN_FALSE; + if (UNEXPECTED(ZEND_LONG_EXCEEDS_INT(offset_arg))) { + zend_argument_value_error(3, "must be between %d and %d", INT32_MIN, INT32_MAX); + RETURN_THROWS(); } - offset = (int32_t)offset_arg; + offset = static_cast(offset_arg); offsetp = &offset; } //else leave offsetp NULL @@ -271,7 +241,7 @@ U_CFUNC PHP_FUNCTION(intltz_get_canonical_id) UnicodeString id; if (intl_stringFromChar(id, str_id, str_id_len, &status) == FAILURE) { intl_error_set(NULL, status, - "could not convert time zone id to UTF-16", 0); + "could not convert time zone id to UTF-16"); RETURN_FALSE; } @@ -305,7 +275,7 @@ U_CFUNC PHP_FUNCTION(intltz_get_region) UnicodeString id; if (intl_stringFromChar(id, str_id, str_id_len, &status) == FAILURE) { intl_error_set(NULL, status, - "could not convert time zone id to UTF-16", 0); + "could not convert time zone id to UTF-16"); RETURN_FALSE; } @@ -340,15 +310,16 @@ U_CFUNC PHP_FUNCTION(intltz_get_equivalent_id) Z_PARAM_LONG(index) ZEND_PARSE_PARAMETERS_END(); - if (UNEXPECTED(index < (zend_long)INT32_MIN || index > (zend_long)INT32_MAX)) { - RETURN_FALSE; + if (UNEXPECTED(ZEND_LONG_EXCEEDS_INT(index))) { + zend_argument_value_error(2, "must be between %d and %d", INT32_MIN, INT32_MAX); + RETURN_THROWS(); } UErrorCode status = UErrorCode(); UnicodeString id; if (intl_stringFromChar(id, str_id, str_id_len, &status) == FAILURE) { intl_error_set(NULL, status, - "could not convert time zone id to UTF-16", 0); + "could not convert time zone id to UTF-16"); RETURN_FALSE; } @@ -375,7 +346,7 @@ U_CFUNC PHP_FUNCTION(intltz_get_iana_id) UnicodeString id; if (intl_stringFromChar(id, str_id, str_id_len, &status) == FAILURE) { intl_error_set(NULL, status, - "could not convert time zone id to UTF-16", 0); + "could not convert time zone id to UTF-16"); RETURN_FALSE; } @@ -484,8 +455,7 @@ U_CFUNC PHP_FUNCTION(intltz_has_same_rules) TIMEZONE_METHOD_FETCH_OBJECT; other_to = Z_INTL_TIMEZONE_P(other_object); if (other_to->utimezone == NULL) { - intl_errors_set(&to->err, U_ILLEGAL_ARGUMENT_ERROR, - "The second IntlTimeZone is unconstructed", 0); + intl_errors_set(&to->err, U_ILLEGAL_ARGUMENT_ERROR, "The second IntlTimeZone is unconstructed"); RETURN_FALSE; } @@ -519,8 +489,7 @@ U_CFUNC PHP_FUNCTION(intltz_get_display_name) found = true; } if (!found) { - intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, - "wrong display type", 0); + intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "wrong display type"); RETURN_FALSE; } @@ -567,7 +536,7 @@ U_CFUNC PHP_FUNCTION(intltz_to_date_time_zone) TIMEZONE_METHOD_FETCH_OBJECT; zval *ret = timezone_convert_to_datetimezone(to->utimezone, - &TIMEZONE_ERROR(to), "intltz_to_date_time_zone", &tmp); + &TIMEZONE_ERROR(to), &tmp); if (ret) { ZVAL_COPY_VALUE(return_value, ret); @@ -630,16 +599,16 @@ U_CFUNC PHP_FUNCTION(intltz_get_windows_id) error = U_ZERO_ERROR; if (intl_stringFromChar(uID, id->val, id->len, &error) == FAILURE) { intl_error_set(NULL, error, - "could not convert time zone id to UTF-16", 0); + "could not convert time zone id to UTF-16"); RETURN_FALSE; } error = U_ZERO_ERROR; TimeZone::getWindowsID(uID, uWinID, error); - INTL_CHECK_STATUS(error, "intltz_get_windows_id: Unable to get timezone from windows ID"); + INTL_CHECK_STATUS(error, "Unable to get timezone from windows ID"); if (uWinID.length() == 0) { intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, - "unknown system timezone", 0); + "unknown system timezone"); RETURN_FALSE; } @@ -668,7 +637,7 @@ U_CFUNC PHP_FUNCTION(intltz_get_id_for_windows_id) error = U_ZERO_ERROR; if (intl_stringFromChar(uWinID, winID->val, winID->len, &error) == FAILURE) { intl_error_set(NULL, error, - "could not convert time zone id to UTF-16", 0); + "could not convert time zone id to UTF-16"); RETURN_FALSE; } @@ -677,7 +646,7 @@ U_CFUNC PHP_FUNCTION(intltz_get_id_for_windows_id) INTL_CHECK_STATUS(error, "unable to get windows ID for timezone"); if (uID.length() == 0) { intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, - "unknown windows timezone", 0); + "unknown windows timezone"); RETURN_FALSE; } diff --git a/ext/intl/transliterator/transliterator_methods.c b/ext/intl/transliterator/transliterator_methods.c index ff3ddf51613..9c1f48608cf 100644 --- a/ext/intl/transliterator/transliterator_methods.c +++ b/ext/intl/transliterator/transliterator_methods.c @@ -48,7 +48,7 @@ static int create_transliterator( char *str_id, size_t str_id_len, zend_long dir if( U_FAILURE( TRANSLITERATOR_ERROR_CODE( to ) ) ) { intl_error_set_code( NULL, TRANSLITERATOR_ERROR_CODE( to ) ); - intl_error_set_custom_msg( NULL, "String conversion of id to UTF-16 failed", 0 ); + intl_error_set_custom_msg( NULL, "String conversion of id to UTF-16 failed"); zval_ptr_dtor( object ); return FAILURE; } @@ -64,15 +64,14 @@ static int create_transliterator( char *str_id, size_t str_id_len, zend_long dir { char *buf = NULL; intl_error_set_code( NULL, TRANSLITERATOR_ERROR_CODE( to ) ); - spprintf( &buf, 0, "transliterator_create: unable to open ICU transliterator" + spprintf( &buf, 0, "unable to open ICU transliterator" " with id \"%s\"", str_id ); if( buf == NULL ) { - intl_error_set_custom_msg( NULL, - "transliterator_create: unable to open ICU transliterator", 0 ); + intl_error_set_custom_msg(NULL, "unable to open ICU transliterator"); } else { - intl_error_set_custom_msg( NULL, buf, /* copy message */ 1 ); + intl_error_set_custom_msg(NULL, buf); efree( buf ); } zval_ptr_dtor( object ); @@ -84,8 +83,7 @@ static int create_transliterator( char *str_id, size_t str_id_len, zend_long dir if( U_FAILURE( TRANSLITERATOR_ERROR_CODE( to ) ) ) { intl_error_set_code( NULL, TRANSLITERATOR_ERROR_CODE( to ) ); - intl_error_set_custom_msg( NULL, - "transliterator_create: internal constructor call failed", 0 ); + intl_error_set_custom_msg(NULL, "internal constructor call failed"); zval_ptr_dtor( object ); return FAILURE; } @@ -169,12 +167,12 @@ PHP_FUNCTION( transliterator_create_from_rules ) char *msg = NULL; smart_str parse_error_str; parse_error_str = intl_parse_error_to_string( &parse_error ); - spprintf( &msg, 0, "transliterator_create_from_rules: unable to " + spprintf( &msg, 0, "unable to " "create ICU transliterator from rules (%s)", parse_error_str.s? ZSTR_VAL(parse_error_str.s) : "" ); smart_str_free( &parse_error_str ); if( msg != NULL ) { - intl_errors_set_custom_msg( INTL_DATA_ERROR_P( to ), msg, 1 ); + intl_errors_set_custom_msg( INTL_DATA_ERROR_P( to ), msg); efree( msg ); } zval_ptr_dtor( return_value ); @@ -182,7 +180,7 @@ PHP_FUNCTION( transliterator_create_from_rules ) } transliterator_object_construct( object, utrans, TRANSLITERATOR_ERROR_CODE_P( to ) ); /* no need to close the transliterator manually on construction error */ - INTL_METHOD_CHECK_STATUS_OR_NULL( to, "transliterator_create_from_rules: internal constructor call failed" ); + INTL_METHOD_CHECK_STATUS_OR_NULL( to, "internal constructor call failed" ); } /* }}} */ @@ -207,11 +205,11 @@ PHP_FUNCTION( transliterator_create_inverse ) TRANSLITERATOR_METHOD_FETCH_OBJECT_NO_CHECK; /* change "to" into new object (from "object" ) */ utrans = utrans_openInverse( to_orig->utrans, TRANSLITERATOR_ERROR_CODE_P( to ) ); - INTL_METHOD_CHECK_STATUS_OR_NULL( to, "transliterator_create_inverse: could not create " + INTL_METHOD_CHECK_STATUS_OR_NULL( to, "could not create " "inverse ICU transliterator" ); transliterator_object_construct( object, utrans, TRANSLITERATOR_ERROR_CODE_P( to ) ); /* no need to close the transliterator manually on construction error */ - INTL_METHOD_CHECK_STATUS_OR_NULL( to, "transliterator_create: internal constructor call failed" ); + INTL_METHOD_CHECK_STATUS_OR_NULL( to, "internal constructor call failed" ); } /* }}} */ @@ -229,7 +227,7 @@ PHP_FUNCTION( transliterator_list_ids ) en = utrans_openIDs( &status ); INTL_CHECK_STATUS( status, - "transliterator_list_ids: Failed to obtain registered transliterators" ); + "Failed to obtain registered transliterators" ); array_init( return_value ); while( (elem = uenum_unext( en, &elem_len, &status )) ) @@ -252,8 +250,8 @@ PHP_FUNCTION( transliterator_list_ids ) { zend_array_destroy( Z_ARR_P(return_value) ); RETVAL_FALSE; - intl_error_set_custom_msg( NULL, "transliterator_list_ids: " - "Failed to build array of registered transliterators", 0 ); + intl_error_set_custom_msg( NULL, + "Failed to build array of registered transliterators"); } } /* }}} */ @@ -342,13 +340,12 @@ PHP_FUNCTION( transliterator_transliterate ) { char *msg; spprintf( &msg, 0, - "transliterator_transliterate: Neither \"start\" nor the \"end\" " + "Neither \"start\" nor the \"end\" " "arguments can exceed the number of UTF-16 code units " "(in this case, %d)", (int) ustr_len ); if(msg != NULL ) { - intl_errors_set( TRANSLITERATOR_ERROR_P( to ), U_ILLEGAL_ARGUMENT_ERROR, - msg, 1 ); + intl_errors_set(TRANSLITERATOR_ERROR_P(to), U_ILLEGAL_ARGUMENT_ERROR, msg); efree( msg ); } goto cleanup; @@ -384,8 +381,7 @@ PHP_FUNCTION( transliterator_transliterate ) else if( U_FAILURE( TRANSLITERATOR_ERROR_CODE( to ) ) ) { intl_error_set_code( NULL, TRANSLITERATOR_ERROR_CODE( to ) ); - intl_errors_set_custom_msg( TRANSLITERATOR_ERROR_P( to ), - "transliterator_transliterate: transliteration failed", 0 ); + intl_errors_set_custom_msg( TRANSLITERATOR_ERROR_P( to ), "transliteration failed"); goto cleanup; } else diff --git a/ext/intl/uchar/uchar.c b/ext/intl/uchar/uchar.cpp similarity index 96% rename from ext/intl/uchar/uchar.c rename to ext/intl/uchar/uchar.cpp index ecfcd8fbe62..f1f777f0ea3 100644 --- a/ext/intl/uchar/uchar.c +++ b/ext/intl/uchar/uchar.cpp @@ -1,3 +1,4 @@ +extern "C" { #include "uchar.h" #include "intl_data.h" #include "intl_convert.h" @@ -6,6 +7,7 @@ #include #include "uchar_arginfo.h" +} #define IC_METHOD(mname) PHP_METHOD(IntlChar, mname) @@ -16,21 +18,21 @@ static inline int convert_cp(UChar32* pcp, zend_string *string_codepoint, zend_l if (ZEND_SIZE_T_INT_OVFL(string_codepoint_length)) { intl_error_set_code(NULL, U_ILLEGAL_ARGUMENT_ERROR); - intl_error_set_custom_msg(NULL, "Input string is too long.", 0); + intl_error_set_custom_msg(NULL, "Input string is too long."); return FAILURE; } U8_NEXT(ZSTR_VAL(string_codepoint), i, string_codepoint_length, int_codepoint); if ((size_t)i != string_codepoint_length) { intl_error_set_code(NULL, U_ILLEGAL_ARGUMENT_ERROR); - intl_error_set_custom_msg(NULL, "Passing a UTF-8 character for codepoint requires a string which is exactly one UTF-8 codepoint long.", 0); + intl_error_set_custom_msg(NULL, "Passing a UTF-8 character for codepoint requires a string which is exactly one UTF-8 codepoint long."); return FAILURE; } } if ((int_codepoint < UCHAR_MIN_VALUE) || (int_codepoint > UCHAR_MAX_VALUE)) { intl_error_set_code(NULL, U_ILLEGAL_ARGUMENT_ERROR); - intl_error_set_custom_msg(NULL, "Codepoint out of range", 0); + intl_error_set_custom_msg(NULL, "Codepoint out of range"); return FAILURE; } *pcp = (UChar32)int_codepoint; @@ -181,7 +183,7 @@ static UBool enumCharType_callback(enumCharType_data *context, if (zend_call_function(&context->fci, &context->fci_cache) == FAILURE) { intl_error_set_code(NULL, U_INTERNAL_PROGRAM_ERROR); - intl_errors_set_custom_msg(NULL, "enumCharTypes callback failed", 0); + intl_errors_set_custom_msg(NULL, "enumCharTypes callback failed"); zval_ptr_dtor(&retval); return 0; } @@ -284,7 +286,7 @@ static UBool enumCharNames_callback(enumCharNames_data *context, if (zend_call_function(&context->fci, &context->fci_cache) == FAILURE) { intl_error_set_code(NULL, U_INTERNAL_PROGRAM_ERROR); - intl_error_set_custom_msg(NULL, "enumCharNames callback failed", 0); + intl_error_set_custom_msg(NULL, "enumCharNames callback failed"); zval_ptr_dtor(&retval); zval_ptr_dtor_str(&args[2]); return 0; @@ -314,7 +316,7 @@ IC_METHOD(enumCharNames) { RETURN_FALSE; } - u_enumCharNames(start, limit, (UEnumCharNamesFn*)enumCharNames_callback, &context, nameChoice, &error); + u_enumCharNames(start, limit, (UEnumCharNamesFn*)enumCharNames_callback, &context, static_cast(nameChoice), &error); INTL_CHECK_STATUS(error, NULL); RETURN_TRUE; } @@ -337,7 +339,7 @@ IC_METHOD(getPropertyName) { RETURN_STRING(ret); } else { intl_error_set_code(NULL, U_ILLEGAL_ARGUMENT_ERROR); - intl_error_set_custom_msg(NULL, "Failed to get property name", 0); + intl_error_set_custom_msg(NULL, "Failed to get property name"); RETURN_FALSE; } } @@ -373,7 +375,7 @@ IC_METHOD(getPropertyValueName) { RETURN_STRING(ret); } else { intl_error_set_code(NULL, U_ILLEGAL_ARGUMENT_ERROR); - intl_error_set_custom_msg(NULL, "Failed to get property name", 0); + intl_error_set_custom_msg(NULL, "Failed to get property name"); RETURN_FALSE; } } @@ -445,7 +447,7 @@ IC_METHOD(digit) { ret = u_digit(cp, radix); if (ret < 0) { intl_error_set_code(NULL, U_ILLEGAL_ARGUMENT_ERROR); - intl_error_set_custom_msg(NULL, "Invalid digit", 0); + intl_error_set_custom_msg(NULL, "Invalid digit"); RETURN_FALSE; } RETURN_LONG(ret); @@ -515,7 +517,7 @@ IC_METHOD(getFC_NFKC_Closure) { if (closure_len == 0) { RETURN_EMPTY_STRING(); } - closure = safe_emalloc(sizeof(UChar), closure_len + 1, 0); + closure = reinterpret_cast(safe_emalloc(sizeof(UChar), closure_len + 1, 0)); error = U_ZERO_ERROR; closure_len = u_getFC_NFKC_Closure(cp, closure, closure_len, &error); if (U_FAILURE(error)) { diff --git a/ext/json/json_encoder.c b/ext/json/json_encoder.c index c147b8eb23d..a7327791540 100644 --- a/ext/json/json_encoder.c +++ b/ext/json/json_encoder.c @@ -41,18 +41,6 @@ static zend_always_inline bool php_json_check_stack_limit(void) #endif } -static int php_json_determine_array_type(zval *val) /* {{{ */ -{ - zend_array *myht = Z_ARRVAL_P(val); - - if (myht) { - return zend_array_is_list(myht) ? PHP_JSON_OUTPUT_ARRAY : PHP_JSON_OUTPUT_OBJECT; - } - - return PHP_JSON_OUTPUT_ARRAY; -} -/* }}} */ - /* {{{ Pretty printing support functions */ static inline void php_json_pretty_print_char(smart_str *buf, int options, char c) /* {{{ */ @@ -63,12 +51,10 @@ static inline void php_json_pretty_print_char(smart_str *buf, int options, char } /* }}} */ -static inline void php_json_pretty_print_indent(smart_str *buf, int options, php_json_encoder *encoder) /* {{{ */ +static inline void php_json_pretty_print_indent(smart_str *buf, int options, const php_json_encoder *encoder) /* {{{ */ { - int i; - if (options & PHP_JSON_PRETTY_PRINT) { - for (i = 0; i < encoder->depth; ++i) { + for (int i = 0; i < encoder->depth; ++i) { smart_str_appendl(buf, " ", 4); } } @@ -122,7 +108,8 @@ static inline void php_json_encode_double(smart_str *buf, double d, int options) static zend_result php_json_encode_array(smart_str *buf, zval *val, int options, php_json_encoder *encoder) /* {{{ */ { - int r, need_comma = 0; + bool encode_as_object = options & PHP_JSON_FORCE_OBJECT; + bool need_comma = false; HashTable *myht, *prop_ht; zend_refcounted *recursion_rc; @@ -138,7 +125,7 @@ static zend_result php_json_encode_array(smart_str *buf, zval *val, int options, myht = Z_ARRVAL_P(val); recursion_rc = (zend_refcounted *)myht; prop_ht = NULL; - r = (options & PHP_JSON_FORCE_OBJECT) ? PHP_JSON_OUTPUT_OBJECT : php_json_determine_array_type(val); + encode_as_object = encode_as_object || !zend_array_is_list(myht); } else if (Z_OBJ_P(val)->properties == NULL && Z_OBJ_HT_P(val)->get_properties_for == NULL && Z_OBJ_HT_P(val)->get_properties == zend_std_get_properties @@ -146,9 +133,7 @@ static zend_result php_json_encode_array(smart_str *buf, zval *val, int options, && !zend_object_is_lazy(Z_OBJ_P(val))) { /* Optimized version without rebuilding properties HashTable */ zend_object *obj = Z_OBJ_P(val); - zend_class_entry *ce = obj->ce; - zend_property_info *prop_info; - zval *prop; + const zend_class_entry *ce = obj->ce; if (GC_IS_RECURSIVE(obj)) { encoder->error_code = PHP_JSON_ERROR_RECURSION; @@ -163,7 +148,7 @@ static zend_result php_json_encode_array(smart_str *buf, zval *val, int options, ++encoder->depth; for (int i = 0; i < ce->default_properties_count; i++) { - prop_info = ce->properties_info_table[i]; + zend_property_info *prop_info = ce->properties_info_table[i]; if (!prop_info) { continue; } @@ -171,7 +156,7 @@ static zend_result php_json_encode_array(smart_str *buf, zval *val, int options, /* Skip protected and private members. */ continue; } - prop = OBJ_PROP(obj, prop_info->offset); + zval *prop = OBJ_PROP(obj, prop_info->offset); if (Z_TYPE_P(prop) == IS_UNDEF) { continue; } @@ -228,7 +213,7 @@ static zend_result php_json_encode_array(smart_str *buf, zval *val, int options, * referenced from a different place in the object graph. */ recursion_rc = (zend_refcounted *)obj; } - r = PHP_JSON_OUTPUT_OBJECT; + encode_as_object = true; } if (recursion_rc && GC_IS_RECURSIVE(recursion_rc)) { @@ -240,7 +225,7 @@ static zend_result php_json_encode_array(smart_str *buf, zval *val, int options, PHP_JSON_HASH_PROTECT_RECURSION(recursion_rc); - if (r == PHP_JSON_OUTPUT_ARRAY) { + if (!encode_as_object) { smart_str_appendc(buf, '['); } else { smart_str_appendc(buf, '{'); @@ -259,7 +244,7 @@ static zend_result php_json_encode_array(smart_str *buf, zval *val, int options, zval tmp; ZVAL_UNDEF(&tmp); - if (r == PHP_JSON_OUTPUT_ARRAY) { + if (!encode_as_object) { ZEND_ASSERT(Z_TYPE_P(data) != IS_PTR); if (need_comma) { @@ -270,7 +255,7 @@ static zend_result php_json_encode_array(smart_str *buf, zval *val, int options, php_json_pretty_print_char(buf, options, '\n'); php_json_pretty_print_indent(buf, options, encoder); - } else if (r == PHP_JSON_OUTPUT_OBJECT) { + } else { if (key) { if (ZSTR_VAL(key)[0] == '\0' && ZSTR_LEN(key) > 0 && Z_TYPE_P(val) == IS_OBJECT) { /* Skip protected and private members. */ @@ -354,7 +339,7 @@ static zend_result php_json_encode_array(smart_str *buf, zval *val, int options, php_json_pretty_print_indent(buf, options, encoder); } - if (r == PHP_JSON_OUTPUT_ARRAY) { + if (!encode_as_object) { smart_str_appendc(buf, ']'); } else { smart_str_appendc(buf, '}'); @@ -369,7 +354,6 @@ zend_result php_json_escape_string( smart_str *buf, const char *s, size_t len, int options, php_json_encoder *encoder) /* {{{ */ { - unsigned int us; size_t pos, checkpoint; char *dst; @@ -407,7 +391,7 @@ zend_result php_json_escape_string( 0xffffffff, 0x500080c4, 0x10000000, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff}; - us = (unsigned char)s[pos]; + unsigned int us = (unsigned char)s[pos]; if (EXPECTED(!ZEND_BIT_TEST(charmap, us))) { pos++; len--; @@ -626,7 +610,7 @@ static zend_result php_json_encode_serializable_object(smart_str *buf, zend_obje 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); + const zend_class_entry *ce = Z_OBJCE_P(val); if (ce->enum_backing_type == IS_UNDEF) { encoder->error_code = PHP_JSON_ERROR_NON_BACKED_ENUM; smart_str_appendc(buf, '0'); diff --git a/ext/json/php_json.h b/ext/json/php_json.h index 00c87eca53c..b79c7c836f7 100644 --- a/ext/json/php_json.h +++ b/ext/json/php_json.h @@ -79,10 +79,6 @@ typedef enum { #define PHP_JSON_INVALID_UTF8_SUBSTITUTE (1<<21) #define PHP_JSON_THROW_ON_ERROR (1<<22) -/* Internal flags */ -#define PHP_JSON_OUTPUT_ARRAY 0 -#define PHP_JSON_OUTPUT_OBJECT 1 - /* default depth */ #define PHP_JSON_PARSER_DEFAULT_DEPTH 512 diff --git a/ext/ldap/ldap.c b/ext/ldap/ldap.c index 0e9f953a2a2..42b9249721e 100644 --- a/ext/ldap/ldap.c +++ b/ext/ldap/ldap.c @@ -32,7 +32,6 @@ #include -#include "ext/standard/dl.h" #include "php_ldap.h" #ifdef PHP_WIN32 @@ -278,7 +277,7 @@ static void php_ldap_zend_string_release_from_char_pointer(char *ptr) { } /* {{{ Parse controls from and to arrays */ -static void _php_ldap_control_to_array(LDAP *ld, LDAPControl* ctrl, zval* array, int request) +static void _php_ldap_control_to_array(LDAP *ld, LDAPControl* ctrl, zval* array, bool request) { array_init(array); @@ -292,10 +291,10 @@ static void _php_ldap_control_to_array(LDAP *ld, LDAPControl* ctrl, zval* array, if (strcmp(ctrl->ldctl_oid, LDAP_CONTROL_PASSWORDPOLICYRESPONSE) == 0) { int expire = 0, grace = 0, rc; LDAPPasswordPolicyError pperr; - zval value; rc = ldap_parse_passwordpolicy_control(ld, ctrl, &expire, &grace, &pperr); if ( rc == LDAP_SUCCESS ) { + zval value; array_init(&value); add_assoc_long(&value, "expire", expire); add_assoc_long(&value, "grace", grace); @@ -310,7 +309,6 @@ static void _php_ldap_control_to_array(LDAP *ld, LDAPControl* ctrl, zval* array, } else if (strcmp(ctrl->ldctl_oid, LDAP_CONTROL_PAGEDRESULTS) == 0) { int lestimated, rc; struct berval lcookie = { 0L, NULL }; - zval value; if (ctrl->ldctl_value.bv_len) { /* ldap_parse_pageresponse_control() allocates lcookie.bv_val */ @@ -321,6 +319,7 @@ static void _php_ldap_control_to_array(LDAP *ld, LDAPControl* ctrl, zval* array, } if ( rc == LDAP_SUCCESS ) { + zval value; array_init(&value); add_assoc_long(&value, "size", lestimated); add_assoc_stringl(&value, "cookie", lcookie.bv_val, lcookie.bv_len); @@ -348,7 +347,6 @@ static void _php_ldap_control_to_array(LDAP *ld, LDAPControl* ctrl, zval* array, add_assoc_stringl(&value, "dn", bv.bv_val, bv.bv_len); while (ber_scanf(ber, "{m" /*}*/, &bv) != LBER_ERROR) { - int i; BerVarray vals = NULL; zval tmp; @@ -358,7 +356,7 @@ static void _php_ldap_control_to_array(LDAP *ld, LDAPControl* ctrl, zval* array, } array_init(&tmp); - for (i = 0; vals[i].bv_val != NULL; i++) { + for (int i = 0; vals[i].bv_val != NULL; i++) { add_next_index_stringl(&tmp, vals[i].bv_val, vals[i].bv_len); } add_assoc_zval(&value, bv.bv_val, &tmp); @@ -372,7 +370,6 @@ static void _php_ldap_control_to_array(LDAP *ld, LDAPControl* ctrl, zval* array, ber_free(ber, 1); } } else if (strcmp(ctrl->ldctl_oid, LDAP_CONTROL_SORTRESPONSE) == 0) { - zval value; int errcode, rc; char* attribute; @@ -382,6 +379,7 @@ static void _php_ldap_control_to_array(LDAP *ld, LDAPControl* ctrl, zval* array, rc = -1; } if ( rc == LDAP_SUCCESS ) { + zval value; array_init(&value); add_assoc_long(&value, "errcode", errcode); if (attribute) { @@ -395,7 +393,6 @@ static void _php_ldap_control_to_array(LDAP *ld, LDAPControl* ctrl, zval* array, } else if (strcmp(ctrl->ldctl_oid, LDAP_CONTROL_VLVRESPONSE) == 0) { int target, count, errcode, rc; struct berval *context; - zval value; if (ctrl->ldctl_value.bv_len) { rc = ldap_parse_vlvresponse_control(ld, ctrl, &target, &count, &context, &errcode); @@ -403,6 +400,7 @@ static void _php_ldap_control_to_array(LDAP *ld, LDAPControl* ctrl, zval* array, rc = -1; } if ( rc == LDAP_SUCCESS ) { + zval value; array_init(&value); add_assoc_long(&value, "target", target); add_assoc_long(&value, "count", count); @@ -486,12 +484,11 @@ static int php_ldap_control_from_array(LDAP *ld, LDAPControl** ctrl, const HashT } } else if (zend_string_equals_literal(control_oid, LDAP_CONTROL_ASSERT)) { zval* tmp; - zend_string* assert; if ((tmp = zend_hash_str_find(Z_ARRVAL_P(val), "filter", sizeof("filter") - 1)) == NULL) { rc = -1; zend_value_error("%s(): Control must have a \"filter\" key", get_active_function_name()); } else { - assert = zval_get_string(tmp); + zend_string* assert = zval_get_string(tmp); if (EG(exception)) { rc = -1; goto failure; @@ -544,15 +541,14 @@ static int php_ldap_control_from_array(LDAP *ld, LDAPControl** ctrl, const HashT rc = -1; php_error_docref(NULL, E_WARNING, "Failed to allocate control value"); } else { - int num_attribs, i; zval* attr; - num_attribs = zend_hash_num_elements(Z_ARRVAL_P(tmp)); + uint32_t num_attribs = zend_hash_num_elements(Z_ARRVAL_P(tmp)); ldap_attrs = safe_emalloc((num_attribs+1), sizeof(char *), 0); tmpstrings1 = safe_emalloc(num_attribs, sizeof(zend_string*), 0); num_tmpstrings1 = 0; - for (i = 0; ilink, msgid, 1 /* LDAP_MSG_ALL */, NULL, &ldap_res); if (rc == -1) { php_error_docref(NULL, E_WARNING, "Bind operation failed"); @@ -1270,7 +1260,7 @@ PHP_FUNCTION(ldap_bind_ext) /* return a PHP control object */ object_init_ex(return_value, ldap_result_ce); - result = Z_LDAP_RESULT_P(return_value); + ldap_resultdata *result = Z_LDAP_RESULT_P(return_value); result->result = ldap_res; } @@ -1491,7 +1481,7 @@ static void php_ldap_do_search(INTERNAL_FUNCTION_PARAMETERS, int scope) LDAPControl **lserverctrls = NULL; int ldap_attrsonly = 0, ldap_sizelimit = -1, ldap_timelimit = -1, ldap_deref = -1; int old_ldap_sizelimit = -1, old_ldap_timelimit = -1, old_ldap_deref = -1; - int ret = 1, ldap_errno, argcount = ZEND_NUM_ARGS(); + bool has_errors = false; ZEND_PARSE_PARAMETERS_START(3, 9) Z_PARAM_ZVAL(link) @@ -1507,7 +1497,7 @@ static void php_ldap_do_search(INTERNAL_FUNCTION_PARAMETERS, int scope) ZEND_PARSE_PARAMETERS_END(); /* Reverse -> fall through */ - switch (argcount) { + switch (ZEND_NUM_ARGS()) { case 9: case 8: ldap_deref = deref; @@ -1546,13 +1536,13 @@ static void php_ldap_do_search(INTERNAL_FUNCTION_PARAMETERS, int scope) ZVAL_DEREF(attribute_zv); if (Z_TYPE_P(attribute_zv) != IS_STRING) { zend_argument_type_error(4, "must be a list of strings, %s given", zend_zval_value_name(attribute_zv)); - ret = 0; + has_errors = true; goto cleanup; } zend_string *attribute = Z_STR_P(attribute_zv); if (zend_str_has_nul_byte(attribute)) { zend_argument_value_error(4, "must not contain strings with any null bytes"); - ret = 0; + has_errors = true; goto cleanup; } ldap_attrs[attribute_index++] = ZSTR_VAL(attribute); @@ -1568,12 +1558,12 @@ process: uint32_t num_links = zend_hash_num_elements(Z_ARRVAL_P(link)); if (num_links == 0) { zend_argument_must_not_be_empty_error(1); - ret = 0; + has_errors = true; goto cleanup; } if (!zend_array_is_list(Z_ARRVAL_P(link))) { zend_argument_value_error(1, "must be a list"); - ret = 0; + has_errors = true; goto cleanup; } @@ -1581,19 +1571,19 @@ process: if (base_dn_ht) { if (!zend_array_is_list(base_dn_ht)) { zend_argument_value_error(2, "must be a list"); - ret = 0; + has_errors = true; goto cleanup; } num_base_dns = zend_hash_num_elements(base_dn_ht); if (num_base_dns != num_links) { zend_argument_value_error(2, "must be the same size as argument #1"); - ret = 0; + has_errors = true; goto cleanup; } } else { if (zend_str_has_nul_byte(base_dn_str)) { zend_argument_value_error(2, "must not contain null bytes"); - ret = 0; + has_errors = true; goto cleanup; } ldap_base_dn = base_dn_str; @@ -1603,19 +1593,19 @@ process: if (filter_ht) { if (!zend_array_is_list(filter_ht)) { zend_argument_value_error(3, "must be a list"); - ret = 0; + has_errors = true; goto cleanup; } num_filters = zend_hash_num_elements(filter_ht); if (num_filters != num_links) { zend_argument_value_error(3, "must be the same size as argument #1"); - ret = 0; + has_errors = true; goto cleanup; } } else { if (zend_str_has_nul_byte(filter_str)) { zend_argument_value_error(3, "must not contain null bytes"); - ret = 0; + has_errors = true; goto cleanup; } ldap_filter = filter_str; @@ -1632,14 +1622,14 @@ process: ZVAL_DEREF(link_zv); if (Z_TYPE_P(link_zv) != IS_OBJECT || !instanceof_function(Z_OBJCE_P(link_zv), ldap_link_ce)) { zend_argument_value_error(1, "must be a list of LDAP\\Connection"); - ret = 0; + has_errors = true; goto cleanup_parallel; } ldap_linkdata *current_ld = Z_LDAP_LINK_P(link_zv); if (!current_ld->link) { zend_throw_error(NULL, "LDAP connection has already been closed"); - ret = 0; + has_errors = true; goto cleanup_parallel; } @@ -1649,13 +1639,13 @@ process: ZVAL_DEREF(base_dn_zv); if (Z_TYPE_P(base_dn_zv) != IS_STRING) { zend_argument_type_error(2, "must be a list of strings, %s given", zend_zval_value_name(base_dn_zv)); - ret = 0; + has_errors = true; goto cleanup_parallel; } ldap_base_dn = Z_STR_P(base_dn_zv); if (zend_str_has_nul_byte(ldap_base_dn)) { zend_argument_value_error(2, "must not contain null bytes"); - ret = 0; + has_errors = true; goto cleanup_parallel; } } @@ -1665,13 +1655,13 @@ process: ZVAL_DEREF(filter_zv); if (Z_TYPE_P(filter_zv) != IS_STRING) { zend_argument_type_error(3, "must be a list of strings, %s given", zend_zval_value_name(filter_zv)); - ret = 0; + has_errors = true; goto cleanup_parallel; } ldap_filter = Z_STR_P(filter_zv); if (zend_str_has_nul_byte(ldap_filter)) { zend_argument_value_error(3, "must not contain null bytes"); - ret = 0; + has_errors = true; goto cleanup_parallel; } } @@ -1721,26 +1711,26 @@ cleanup_parallel: ld = Z_LDAP_LINK_P(link); if (!ld->link) { zend_throw_error(NULL, "LDAP connection has already been closed"); - ret = 0; + has_errors = true; goto cleanup; } if (!base_dn_str) { zend_argument_type_error(2, "must be of type string when argument #1 ($ldap) is an LDAP\\Connection instance"); - ret = 0; + has_errors = true; goto cleanup; } if (!filter_str) { zend_argument_type_error(3, "must be of type string when argument #1 ($ldap) is an LDAP\\Connection instance"); - ret = 0; + has_errors = true; goto cleanup; } if (server_controls_ht) { lserverctrls = php_ldap_controls_from_array(ld->link, server_controls_ht, 9); if (lserverctrls == NULL) { - ret = 0; + has_errors = true; goto cleanup; } } @@ -1748,7 +1738,7 @@ cleanup_parallel: php_set_opts(ld->link, ldap_sizelimit, ldap_timelimit, ldap_deref, &old_ldap_sizelimit, &old_ldap_timelimit, &old_ldap_deref); /* Run the actual search */ - ldap_errno = ldap_search_ext_s(ld->link, ZSTR_VAL(base_dn_str), scope, ZSTR_VAL(filter_str), ldap_attrs, ldap_attrsonly, lserverctrls, NULL, NULL, ldap_sizelimit, &ldap_res); + int ldap_errno = ldap_search_ext_s(ld->link, ZSTR_VAL(base_dn_str), scope, ZSTR_VAL(filter_str), ldap_attrs, ldap_attrsonly, lserverctrls, NULL, NULL, ldap_sizelimit, &ldap_res); if (ldap_errno != LDAP_SUCCESS && ldap_errno != LDAP_SIZELIMIT_EXCEEDED @@ -1765,7 +1755,7 @@ cleanup_parallel: ldap_msgfree(ldap_res); } php_error_docref(NULL, E_WARNING, "Search: %s", ldap_err2string(ldap_errno)); - ret = 0; + has_errors = true; } else { if (ldap_errno == LDAP_SIZELIMIT_EXCEEDED) { php_error_docref(NULL, E_WARNING, "Partial search results returned: Sizelimit exceeded"); @@ -1791,8 +1781,8 @@ cleanup: if (ldap_attrs != NULL) { efree(ldap_attrs); } - if (!ret) { - RETVAL_BOOL(ret); + if (has_errors) { + RETVAL_FALSE; } if (lserverctrls) { _php_ldap_controls_free(&lserverctrls); @@ -1866,7 +1856,6 @@ PHP_FUNCTION(ldap_first_entry) { zval *link, *result; ldap_linkdata *ld; - ldap_result_entry *resultentry; ldap_resultdata *ldap_result; LDAPMessage *entry; @@ -1884,7 +1873,7 @@ PHP_FUNCTION(ldap_first_entry) RETVAL_FALSE; } else { object_init_ex(return_value, ldap_result_entry_ce); - resultentry = Z_LDAP_RESULT_ENTRY_P(return_value); + ldap_result_entry *resultentry = Z_LDAP_RESULT_ENTRY_P(return_value); ZVAL_COPY(&resultentry->res, result); resultentry->data = entry; resultentry->ber = NULL; @@ -1897,7 +1886,7 @@ PHP_FUNCTION(ldap_next_entry) { zval *link, *result_entry; ldap_linkdata *ld; - ldap_result_entry *resultentry, *resultentry_next; + ldap_result_entry *resultentry; LDAPMessage *entry_next; if (zend_parse_parameters(ZEND_NUM_ARGS(), "OO", &link, ldap_link_ce, &result_entry, ldap_result_entry_ce) != SUCCESS) { @@ -1913,7 +1902,7 @@ PHP_FUNCTION(ldap_next_entry) RETVAL_FALSE; } else { object_init_ex(return_value, ldap_result_entry_ce); - resultentry_next = Z_LDAP_RESULT_ENTRY_P(return_value); + ldap_result_entry *resultentry_next = Z_LDAP_RESULT_ENTRY_P(return_value); ZVAL_COPY(&resultentry_next->res, &resultentry->res); resultentry_next->data = entry_next; resultentry_next->ber = NULL; @@ -1927,14 +1916,10 @@ PHP_FUNCTION(ldap_get_entries) zval *link, *result; ldap_resultdata *ldap_result; LDAPMessage *ldap_result_entry; - zval tmp1, tmp2; ldap_linkdata *ld; LDAP *ldap; - int num_entries, num_attrib, num_values, i; + int num_entries; BerElement *ber; - char *attribute; - size_t attr_len; - struct berval **ldap_value; char *dn; if (zend_parse_parameters(ZEND_NUM_ARGS(), "OO", &link, ldap_link_ce, &result, ldap_result_ce) != SUCCESS) { @@ -1965,23 +1950,25 @@ PHP_FUNCTION(ldap_get_entries) num_entries = 0; while (ldap_result_entry != NULL) { + zval tmp1; array_init(&tmp1); - num_attrib = 0; - attribute = ldap_first_attribute(ldap, ldap_result_entry, &ber); + int num_attrib = 0; + char *attribute = ldap_first_attribute(ldap, ldap_result_entry, &ber); while (attribute != NULL) { - ldap_value = ldap_get_values_len(ldap, ldap_result_entry, attribute); - num_values = ldap_count_values_len(ldap_value); + struct berval **ldap_value = ldap_get_values_len(ldap, ldap_result_entry, attribute); + int num_values = ldap_count_values_len(ldap_value); + zval tmp2; array_init(&tmp2); add_assoc_long(&tmp2, "count", num_values); - for (i = 0; i < num_values; i++) { + for (int i = 0; i < num_values; i++) { add_index_stringl(&tmp2, i, ldap_value[i]->bv_val, ldap_value[i]->bv_len); } ldap_value_free_len(ldap_value); - attr_len = strlen(attribute); + size_t attr_len = strlen(attribute); zend_str_tolower(attribute, attr_len); zend_hash_str_update(Z_ARRVAL(tmp1), attribute, attr_len, &tmp2); add_index_string(&tmp1, num_attrib, attribute); @@ -2093,12 +2080,10 @@ PHP_FUNCTION(ldap_next_attribute) PHP_FUNCTION(ldap_get_attributes) { zval *link, *result_entry; - zval tmp; ldap_linkdata *ld; ldap_result_entry *resultentry; char *attribute; - struct berval **ldap_value; - int i, num_values, num_attrib; + int num_attrib; BerElement *ber; if (zend_parse_parameters(ZEND_NUM_ARGS(), "OO", &link, ldap_link_ce, &result_entry, ldap_result_entry_ce) != SUCCESS) { @@ -2115,12 +2100,13 @@ PHP_FUNCTION(ldap_get_attributes) attribute = ldap_first_attribute(ld->link, resultentry->data, &ber); while (attribute != NULL) { - ldap_value = ldap_get_values_len(ld->link, resultentry->data, attribute); - num_values = ldap_count_values_len(ldap_value); + struct berval **ldap_value = ldap_get_values_len(ld->link, resultentry->data, attribute); + int num_values = ldap_count_values_len(ldap_value); + zval tmp; array_init(&tmp); add_assoc_long(&tmp, "count", num_values); - for (i = 0; i < num_values; i++) { + for (int i = 0; i < num_values; i++) { add_index_stringl(&tmp, i, ldap_value[i]->bv_val, ldap_value[i]->bv_len); } ldap_value_free_len(ldap_value); @@ -2152,7 +2138,7 @@ PHP_FUNCTION(ldap_get_values_len) ldap_result_entry *resultentry; char *attr; struct berval **ldap_value_len; - int i, num_values; + int num_values; size_t attr_len; if (zend_parse_parameters(ZEND_NUM_ARGS(), "OOp", &link, ldap_link_ce, &result_entry, ldap_result_entry_ce, &attr, &attr_len) != SUCCESS) { @@ -2172,7 +2158,7 @@ PHP_FUNCTION(ldap_get_values_len) num_values = ldap_count_values_len(ldap_value_len); array_init(return_value); - for (i=0; ibv_val, ldap_value_len[i]->bv_len); } @@ -2267,7 +2253,7 @@ PHP_FUNCTION(ldap_dn2ufn) /* added to fix use of ldap_modify_add for doing an ldap_add, gerrit thomson. */ #define PHP_LD_FULL_ADD 0xff /* {{{ php_ldap_do_modify */ -static void php_ldap_do_modify(INTERNAL_FUNCTION_PARAMETERS, int oper, int ext) +static void php_ldap_do_modify(INTERNAL_FUNCTION_PARAMETERS, int oper, bool ext) { zval *link; ldap_linkdata *ld; @@ -2279,7 +2265,7 @@ static void php_ldap_do_modify(INTERNAL_FUNCTION_PARAMETERS, int oper, int ext) ldap_resultdata *result; LDAPMessage *ldap_res; size_t dn_len; - int is_full_add=0; /* flag for full add operation so ldap_mod_add can be put back into oper, gerrit THomson */ + bool is_full_add = false; /* flag for full add operation so ldap_mod_add can be put back into oper, gerrit THomson */ if (zend_parse_parameters(ZEND_NUM_ARGS(), "Oph/|h!", &link, ldap_link_ce, &dn, &dn_len, &attributes_ht, &server_controls_ht) != SUCCESS) { RETURN_THROWS(); @@ -2301,7 +2287,7 @@ static void php_ldap_do_modify(INTERNAL_FUNCTION_PARAMETERS, int oper, int ext) /* added by gerrit thomson to fix ldap_add using ldap_mod_add */ if (oper == PHP_LD_FULL_ADD) { oper = LDAP_MOD_ADD; - is_full_add = 1; + is_full_add = true; } /* end additional , gerrit thomson */ @@ -2396,7 +2382,7 @@ static void php_ldap_do_modify(INTERNAL_FUNCTION_PARAMETERS, int oper, int ext) /* check flag to see if do_mod was called to perform full add , gerrit thomson */ int ldap_status_code = LDAP_SUCCESS; int msgid; - if (is_full_add == 1) { + if (is_full_add) { if (ext) { ldap_status_code = ldap_add_ext(ld->link, dn, ldap_mods, lserverctrls, NULL, &msgid); } else { @@ -2469,14 +2455,14 @@ cleanup: PHP_FUNCTION(ldap_add) { /* use a newly define parameter into the do_modify so ldap_mod_add can be used the way it is supposed to be used , Gerrit THomson */ - php_ldap_do_modify(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_LD_FULL_ADD, 0); + php_ldap_do_modify(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_LD_FULL_ADD, false); } /* }}} */ /* {{{ Add entries to LDAP directory */ PHP_FUNCTION(ldap_add_ext) { - php_ldap_do_modify(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_LD_FULL_ADD, 1); + php_ldap_do_modify(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_LD_FULL_ADD, true); } /* }}} */ @@ -2485,54 +2471,52 @@ PHP_FUNCTION(ldap_add_ext) /* {{{ Replace attribute values with new ones */ PHP_FUNCTION(ldap_mod_replace) { - php_ldap_do_modify(INTERNAL_FUNCTION_PARAM_PASSTHRU, LDAP_MOD_REPLACE, 0); + php_ldap_do_modify(INTERNAL_FUNCTION_PARAM_PASSTHRU, LDAP_MOD_REPLACE, false); } /* }}} */ /* {{{ Replace attribute values with new ones */ PHP_FUNCTION(ldap_mod_replace_ext) { - php_ldap_do_modify(INTERNAL_FUNCTION_PARAM_PASSTHRU, LDAP_MOD_REPLACE, 1); + php_ldap_do_modify(INTERNAL_FUNCTION_PARAM_PASSTHRU, LDAP_MOD_REPLACE, true); } /* }}} */ /* {{{ Add attribute values to current */ PHP_FUNCTION(ldap_mod_add) { - php_ldap_do_modify(INTERNAL_FUNCTION_PARAM_PASSTHRU, LDAP_MOD_ADD, 0); + php_ldap_do_modify(INTERNAL_FUNCTION_PARAM_PASSTHRU, LDAP_MOD_ADD, false); } /* }}} */ /* {{{ Add attribute values to current */ PHP_FUNCTION(ldap_mod_add_ext) { - php_ldap_do_modify(INTERNAL_FUNCTION_PARAM_PASSTHRU, LDAP_MOD_ADD, 1); + php_ldap_do_modify(INTERNAL_FUNCTION_PARAM_PASSTHRU, LDAP_MOD_ADD, true); } /* }}} */ /* {{{ Delete attribute values */ PHP_FUNCTION(ldap_mod_del) { - php_ldap_do_modify(INTERNAL_FUNCTION_PARAM_PASSTHRU, LDAP_MOD_DELETE, 0); + php_ldap_do_modify(INTERNAL_FUNCTION_PARAM_PASSTHRU, LDAP_MOD_DELETE, false); } /* }}} */ /* {{{ Delete attribute values */ PHP_FUNCTION(ldap_mod_del_ext) { - php_ldap_do_modify(INTERNAL_FUNCTION_PARAM_PASSTHRU, LDAP_MOD_DELETE, 1); + php_ldap_do_modify(INTERNAL_FUNCTION_PARAM_PASSTHRU, LDAP_MOD_DELETE, true); } /* }}} */ /* {{{ php_ldap_do_delete */ -static void php_ldap_do_delete(INTERNAL_FUNCTION_PARAMETERS, int ext) +static void php_ldap_do_delete(INTERNAL_FUNCTION_PARAMETERS, bool ext) { zval *link; HashTable *server_controls_ht = NULL; ldap_linkdata *ld; LDAPControl **lserverctrls = NULL; - ldap_resultdata *result; - LDAPMessage *ldap_res; char *dn; int rc, msgid; size_t dn_len; @@ -2562,6 +2546,7 @@ static void php_ldap_do_delete(INTERNAL_FUNCTION_PARAMETERS, int ext) RETVAL_FALSE; goto cleanup; } else if (ext) { + LDAPMessage *ldap_res; rc = ldap_result(ld->link, msgid, 1 /* LDAP_MSG_ALL */, NULL, &ldap_res); if (rc == -1) { php_error_docref(NULL, E_WARNING, "Delete operation failed"); @@ -2571,7 +2556,7 @@ static void php_ldap_do_delete(INTERNAL_FUNCTION_PARAMETERS, int ext) /* return a PHP control object */ object_init_ex(return_value, ldap_result_ce); - result = Z_LDAP_RESULT_P(return_value); + ldap_resultdata *result = Z_LDAP_RESULT_P(return_value); result->result = ldap_res; } else { RETVAL_TRUE; @@ -2589,14 +2574,14 @@ cleanup: /* {{{ Delete an entry from a directory */ PHP_FUNCTION(ldap_delete) { - php_ldap_do_delete(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0); + php_ldap_do_delete(INTERNAL_FUNCTION_PARAM_PASSTHRU, false); } /* }}} */ /* {{{ Delete an entry from a directory */ PHP_FUNCTION(ldap_delete_ext) { - php_ldap_do_delete(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1); + php_ldap_do_delete(INTERNAL_FUNCTION_PARAM_PASSTHRU, true); } /* }}} */ @@ -3148,7 +3133,7 @@ PHP_FUNCTION(ldap_get_option) } RETURN_FALSE; } - _php_ldap_controls_to_array(ldap, ctrls, retval, 1); + _php_ldap_controls_to_array(ldap, ctrls, retval, true); } break; /* options not implemented case LDAP_OPT_API_INFO: @@ -3342,7 +3327,6 @@ PHP_FUNCTION(ldap_set_option) case LDAP_OPT_CLIENT_CONTROLS: { LDAPControl **ctrls; - int rc; if (Z_TYPE_P(newval) != IS_ARRAY) { zend_argument_type_error(3, "must be of type array for the LDAP_OPT_CLIENT_CONTROLS option, %s given", zend_zval_value_name(newval)); @@ -3354,7 +3338,7 @@ PHP_FUNCTION(ldap_set_option) if (ctrls == NULL) { RETURN_FALSE; } else { - rc = ldap_set_option(ldap, option, ctrls); + int rc = ldap_set_option(ldap, option, ctrls); _php_ldap_controls_free(&ctrls); if (rc != LDAP_SUCCESS) { RETURN_FALSE; @@ -3377,7 +3361,7 @@ PHP_FUNCTION(ldap_parse_result) ldap_linkdata *ld; ldap_resultdata *ldap_result; LDAPControl **lserverctrls = NULL; - char **lreferrals, **refp; + char **lreferrals; char *lmatcheddn, *lerrmsg; int rc, lerrcode; @@ -3405,7 +3389,7 @@ PHP_FUNCTION(ldap_parse_result) ZEND_TRY_ASSIGN_REF_LONG(errcode, lerrcode); if (serverctrls) { - _php_ldap_controls_to_array(ld->link, lserverctrls, serverctrls, 0); + _php_ldap_controls_to_array(ld->link, lserverctrls, serverctrls, false); } if (referrals) { referrals = zend_try_array_init(referrals); @@ -3413,7 +3397,7 @@ PHP_FUNCTION(ldap_parse_result) RETURN_THROWS(); } if (lreferrals != NULL) { - refp = lreferrals; + char **refp = lreferrals; while (*refp) { add_next_index_string(referrals, *refp); refp++; @@ -3526,7 +3510,6 @@ PHP_FUNCTION(ldap_first_reference) { zval *link, *result; ldap_linkdata *ld; - ldap_result_entry *resultentry; ldap_resultdata *ldap_result; LDAPMessage *entry; @@ -3544,7 +3527,7 @@ PHP_FUNCTION(ldap_first_reference) RETVAL_FALSE; } else { object_init_ex(return_value, ldap_result_entry_ce); - resultentry = Z_LDAP_RESULT_ENTRY_P(return_value); + ldap_result_entry *resultentry = Z_LDAP_RESULT_ENTRY_P(return_value); ZVAL_COPY(&resultentry->res, result); resultentry->data = entry; resultentry->ber = NULL; @@ -3557,7 +3540,7 @@ PHP_FUNCTION(ldap_next_reference) { zval *link, *result_entry; ldap_linkdata *ld; - ldap_result_entry *resultentry, *resultentry_next; + ldap_result_entry *resultentry; LDAPMessage *entry_next; if (zend_parse_parameters(ZEND_NUM_ARGS(), "OO", &link, ldap_link_ce, &result_entry, ldap_result_entry_ce) != SUCCESS) { @@ -3573,7 +3556,7 @@ PHP_FUNCTION(ldap_next_reference) RETVAL_FALSE; } else { object_init_ex(return_value, ldap_result_entry_ce); - resultentry_next = Z_LDAP_RESULT_ENTRY_P(return_value); + ldap_result_entry *resultentry_next = Z_LDAP_RESULT_ENTRY_P(return_value); ZVAL_COPY(&resultentry_next->res, &resultentry->res); resultentry_next->data = entry_next; resultentry_next->ber = NULL; @@ -3588,7 +3571,7 @@ PHP_FUNCTION(ldap_parse_reference) zval *link, *result_entry, *referrals; ldap_linkdata *ld; ldap_result_entry *resultentry; - char **lreferrals, **refp; + char **lreferrals; if (zend_parse_parameters(ZEND_NUM_ARGS(), "OOz", &link, ldap_link_ce, &result_entry, ldap_result_entry_ce, &referrals) != SUCCESS) { RETURN_THROWS(); @@ -3609,7 +3592,7 @@ PHP_FUNCTION(ldap_parse_reference) } if (lreferrals != NULL) { - refp = lreferrals; + char **refp = lreferrals; while (*refp) { add_next_index_string(referrals, *refp); refp++; @@ -3622,12 +3605,11 @@ PHP_FUNCTION(ldap_parse_reference) #endif /* {{{ php_ldap_do_rename */ -static void php_ldap_do_rename(INTERNAL_FUNCTION_PARAMETERS, int ext) +static void php_ldap_do_rename(INTERNAL_FUNCTION_PARAMETERS, bool ext) { zval *link; ldap_linkdata *ld; LDAPControl **lserverctrls = NULL; - ldap_resultdata *result; LDAPMessage *ldap_res; int rc, msgid; char *dn, *newrdn, *newparent; @@ -3689,7 +3671,7 @@ static void php_ldap_do_rename(INTERNAL_FUNCTION_PARAMETERS, int ext) /* return a PHP control object */ object_init_ex(return_value, ldap_result_ce); - result = Z_LDAP_RESULT_P(return_value); + ldap_resultdata *result = Z_LDAP_RESULT_P(return_value); result->result = ldap_res; } else { RETVAL_TRUE; @@ -3707,14 +3689,14 @@ cleanup: /* {{{ Modify the name of an entry */ PHP_FUNCTION(ldap_rename) { - php_ldap_do_rename(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0); + php_ldap_do_rename(INTERNAL_FUNCTION_PARAM_PASSTHRU, false); } /* }}} */ /* {{{ Modify the name of an entry */ PHP_FUNCTION(ldap_rename_ext) { - php_ldap_do_rename(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1); + php_ldap_do_rename(INTERNAL_FUNCTION_PARAM_PASSTHRU, true); } /* }}} */ @@ -3725,7 +3707,8 @@ PHP_FUNCTION(ldap_rename_ext) */ static int _php_ldap_tls_newctx(LDAP *ld) { - int val = 0, i, opts[] = { + int val = 0, i; + int str_opts[] = { #if (LDAP_API_VERSION > 2000) LDAP_OPT_X_TLS_CACERTDIR, LDAP_OPT_X_TLS_CACERTFILE, @@ -3745,21 +3728,42 @@ static int _php_ldap_tls_newctx(LDAP *ld) #endif 0}; - for (i=0 ; opts[i] ; i++) { + for (i=0 ; str_opts[i] ; i++) { char *path = NULL; - ldap_get_option(ld, opts[i], &path); + ldap_get_option(ld, str_opts[i], &path); if (path) { /* already set locally */ ldap_memfree(path); } else { - ldap_get_option(NULL, opts[i], &path); + ldap_get_option(NULL, str_opts[i], &path); if (path) { /* set globally, inherit */ - ldap_set_option(ld, opts[i], path); + ldap_set_option(ld, str_opts[i], path); ldap_memfree(path); } } } +#ifdef LDAP_OPT_X_TLS_PROTOCOL_MIN + int int_opts[] = { + LDAP_OPT_X_TLS_PROTOCOL_MIN, +#ifdef LDAP_OPT_X_TLS_PROTOCOL_MAX + LDAP_OPT_X_TLS_PROTOCOL_MAX, +#endif + 0 + }; + for (i=0 ; int_opts[i] ; i++) { + int value = 0; + + ldap_get_option(ld, int_opts[i], &value); + if (value <= 0) { /* if value is not set already */ + ldap_get_option(NULL, int_opts[i], &value); + if (value > 0) { /* set globally, inherit */ + ldap_set_option(ld, int_opts[i], &value); + } + } + } +#endif + return ldap_set_option(ld, LDAP_OPT_X_TLS_NEWCTX, &val); } @@ -3795,7 +3799,7 @@ PHP_FUNCTION(ldap_start_tls) #if defined(LDAP_API_FEATURE_X_OPENLDAP) && defined(HAVE_3ARG_SETREBINDPROC) /* {{{ _ldap_rebind_proc() */ -int _ldap_rebind_proc(LDAP *ldap, const char *url, ber_tag_t req, ber_int_t msgid, void *params) +static int _ldap_rebind_proc(LDAP *ldap, const char *url, ber_tag_t req, ber_int_t msgid, void *params) { ldap_linkdata *ld = NULL; int retval; @@ -3916,7 +3920,7 @@ static zend_string* php_ldap_do_escape(const bool *map, const char *value, size_ return ret; } -static void php_ldap_escape_map_set_chars(bool *map, const char *chars, const size_t charslen, char escape) +static void php_ldap_escape_map_set_chars(bool *map, const char *chars, const size_t charslen, bool escape) { size_t i = 0; while (i < charslen) { @@ -3928,7 +3932,6 @@ PHP_FUNCTION(ldap_escape) { char *value, *ignores; size_t valuelen = 0, ignoreslen = 0; - int i; zend_long flags = 0; bool map[256] = {0}, havecharlist = 0; @@ -3942,22 +3945,22 @@ PHP_FUNCTION(ldap_escape) if (flags & PHP_LDAP_ESCAPE_FILTER) { havecharlist = 1; - php_ldap_escape_map_set_chars(map, "\\*()\0", sizeof("\\*()\0") - 1, 1); + php_ldap_escape_map_set_chars(map, "\\*()\0", sizeof("\\*()\0") - 1, true); } if (flags & PHP_LDAP_ESCAPE_DN) { havecharlist = 1; - php_ldap_escape_map_set_chars(map, "\\,=+<>;\"#\r", sizeof("\\,=+<>;\"#\r") - 1, 1); + php_ldap_escape_map_set_chars(map, "\\,=+<>;\"#\r", sizeof("\\,=+<>;\"#\r") - 1, true); } if (!havecharlist) { - for (i = 0; i < 256; i++) { + for (uint16_t i = 0; i < 256; i++) { map[i] = 1; } } if (ignoreslen) { - php_ldap_escape_map_set_chars(map, ignores, ignoreslen, 0); + php_ldap_escape_map_set_chars(map, ignores, ignoreslen, false); } zend_string *result = php_ldap_do_escape(map, value, valuelen, flags); @@ -4212,7 +4215,7 @@ PHP_FUNCTION(ldap_exop_passwd) } if (serverctrls) { - _php_ldap_controls_to_array(ld->link, lserverctrls, serverctrls, 0); + _php_ldap_controls_to_array(ld->link, lserverctrls, serverctrls, false); } /* return */ diff --git a/ext/ldap/tests/ldap_start_tls_rc_max_version.conf b/ext/ldap/tests/ldap_start_tls_rc_max_version.conf new file mode 100644 index 00000000000..0cd03f8b8e1 --- /dev/null +++ b/ext/ldap/tests/ldap_start_tls_rc_max_version.conf @@ -0,0 +1 @@ +TLS_PROTOCOL_MAX 3.2 \ No newline at end of file diff --git a/ext/ldap/tests/ldap_start_tls_rc_max_version.phpt b/ext/ldap/tests/ldap_start_tls_rc_max_version.phpt new file mode 100644 index 00000000000..e983b97c4b4 --- /dev/null +++ b/ext/ldap/tests/ldap_start_tls_rc_max_version.phpt @@ -0,0 +1,45 @@ +--TEST-- +ldap_start_tls() - Basic ldap_start_tls test +--EXTENSIONS-- +ldap +--ENV-- +LDAPCONF={PWD}/ldap_start_tls_rc_max_version.conf +--SKIPIF-- + "OpenLDAP", + "min_version" => 20600, +]; +require_once __DIR__ .'/skipifbindfailure.inc'; +?> +--FILE-- + +--EXPECT-- +bool(false) +bool(false) +bool(false) diff --git a/ext/ldap/tests/skipifbindfailure.inc b/ext/ldap/tests/skipifbindfailure.inc index 1a0d0c6d199..81c7998cfbb 100644 --- a/ext/ldap/tests/skipifbindfailure.inc +++ b/ext/ldap/tests/skipifbindfailure.inc @@ -10,4 +10,37 @@ if ($skip_on_bind_failure) { ldap_unbind($link); } + +if (isset($require_vendor)) { + ob_start(); + phpinfo(INFO_MODULES); + $phpinfo = ob_get_clean(); + + // Extract the LDAP section specifically + if (preg_match('/^ldap\s*$(.*?)^[a-z_]+\s*$/ims', $phpinfo, $ldap_section_match)) { + $ldap_section = $ldap_section_match[1]; + + // Extract vendor info from the LDAP section only + if (preg_match('/Vendor Name\s*=>\s*(.+)/i', $ldap_section, $name_match) && + preg_match('/Vendor Version\s*=>\s*(\d+)/i', $ldap_section, $version_match)) { + + $vendor_name = trim($name_match[1]); + $vendor_version = (int)$version_match[1]; + + // Check vendor name if specified + if (isset($require_vendor['name']) && $vendor_name !== $require_vendor['name']) { + die("skip Requires {$require_vendor['name']} (detected: $vendor_name)"); + } + + // Check minimum version if specified + if (isset($require_vendor['min_version']) && $vendor_version < $require_vendor['min_version']) { + die("skip Requires minimum version {$require_vendor['min_version']} (detected: $vendor_version)"); + } + } else { + die("skip Cannot determine LDAP vendor information"); + } + } else { + die("skip LDAP extension information not found"); + } +} ?> diff --git a/ext/lexbor/lexbor/core/in.c b/ext/lexbor/lexbor/core/in.c index 9214e198950..951e585cbd3 100644 --- a/ext/lexbor/lexbor/core/in.c +++ b/ext/lexbor/lexbor/core/in.c @@ -65,7 +65,7 @@ lexbor_in_node_make(lexbor_in_t *incoming, lexbor_in_node_t *last_node, node->opt = LEXBOR_IN_OPT_UNDEF; node->begin = buf; - node->end = buf + buf_size; + node->end = buf ? (buf + buf_size) : NULL; node->use = buf; if (last_node != NULL) { diff --git a/ext/lexbor/lexbor/core/str.c b/ext/lexbor/lexbor/core/str.c index 0f04286bdea..d11a08614dd 100644 --- a/ext/lexbor/lexbor/core/str.c +++ b/ext/lexbor/lexbor/core/str.c @@ -133,6 +133,10 @@ lexbor_str_append(lexbor_str_t *str, lexbor_mraw_t *mraw, { lxb_char_t *data_begin; + if (length == 0) { + return str->data; + } + lexbor_str_check_size_arg_m(str, lexbor_str_size(str), mraw, (length + 1), NULL); diff --git a/ext/lexbor/lexbor/dom/interfaces/node.c b/ext/lexbor/lexbor/dom/interfaces/node.c index ade06fca179..a588ed388e4 100644 --- a/ext/lexbor/lexbor/dom/interfaces/node.c +++ b/ext/lexbor/lexbor/dom/interfaces/node.c @@ -248,11 +248,6 @@ lxb_dom_node_t * lxb_dom_node_destroy(lxb_dom_node_t *node) { lxb_dom_node_remove(node); - - if (node->owner_document->node_cb->destroy != NULL) { - node->owner_document->node_cb->destroy(node); - } - return lxb_dom_document_destroy_interface(node); } diff --git a/ext/lexbor/lexbor/html/interface_res.h b/ext/lexbor/lexbor/html/interface_res.h index 08667af19ba..980be3c7de0 100644 --- a/ext/lexbor/lexbor/html/interface_res.h +++ b/ext/lexbor/lexbor/html/interface_res.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 Alexander Borisov + * Copyright (C) 2018-2025 Alexander Borisov * * Author: Alexander Borisov */ @@ -118,6 +118,907 @@ #include "lexbor/html/interfaces/video_element.h" #include "lexbor/html/interfaces/window.h" +lxb_inline void * +lxb_dom_element_interface_create_wrapper(void *interface) +{ + return lxb_dom_element_interface_create(interface); +} + +lxb_inline void * +lxb_dom_element_interface_destroy_wrapper(void *interface) +{ + return lxb_dom_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_unknown_element_interface_create_wrapper(void *interface) +{ + return lxb_html_unknown_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_unknown_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_unknown_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_element_interface_create_wrapper(void *interface) +{ + return lxb_html_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_dom_text_interface_create_wrapper(void *interface) +{ + return lxb_dom_text_interface_create(interface); +} + +lxb_inline void * +lxb_dom_text_interface_destroy_wrapper(void *interface) +{ + return lxb_dom_text_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_document_interface_create_wrapper(void *interface) +{ + return lxb_html_document_interface_create(interface); +} + +lxb_inline void * +lxb_html_document_interface_destroy_wrapper(void *interface) +{ + return lxb_html_document_interface_destroy(interface); +} + +lxb_inline void * +lxb_dom_comment_interface_create_wrapper(void *interface) +{ + return lxb_dom_comment_interface_create(interface); +} + +lxb_inline void * +lxb_dom_comment_interface_destroy_wrapper(void *interface) +{ + return lxb_dom_comment_interface_destroy(interface); +} + +lxb_inline void * +lxb_dom_document_type_interface_create_wrapper(void *interface) +{ + return lxb_dom_document_type_interface_create(interface); +} + +lxb_inline void * +lxb_dom_document_type_interface_destroy_wrapper(void *interface) +{ + return lxb_dom_document_type_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_anchor_element_interface_create_wrapper(void *interface) +{ + return lxb_html_anchor_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_anchor_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_anchor_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_area_element_interface_create_wrapper(void *interface) +{ + return lxb_html_area_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_area_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_area_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_audio_element_interface_create_wrapper(void *interface) +{ + return lxb_html_audio_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_audio_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_audio_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_base_element_interface_create_wrapper(void *interface) +{ + return lxb_html_base_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_base_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_base_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_quote_element_interface_create_wrapper(void *interface) +{ + return lxb_html_quote_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_quote_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_quote_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_body_element_interface_create_wrapper(void *interface) +{ + return lxb_html_body_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_body_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_body_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_br_element_interface_create_wrapper(void *interface) +{ + return lxb_html_br_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_br_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_br_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_button_element_interface_create_wrapper(void *interface) +{ + return lxb_html_button_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_button_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_button_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_canvas_element_interface_create_wrapper(void *interface) +{ + return lxb_html_canvas_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_canvas_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_canvas_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_table_caption_element_interface_create_wrapper(void *interface) +{ + return lxb_html_table_caption_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_table_caption_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_table_caption_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_table_col_element_interface_create_wrapper(void *interface) +{ + return lxb_html_table_col_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_table_col_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_table_col_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_data_element_interface_create_wrapper(void *interface) +{ + return lxb_html_data_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_data_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_data_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_data_list_element_interface_create_wrapper(void *interface) +{ + return lxb_html_data_list_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_data_list_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_data_list_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_mod_element_interface_create_wrapper(void *interface) +{ + return lxb_html_mod_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_mod_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_mod_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_details_element_interface_create_wrapper(void *interface) +{ + return lxb_html_details_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_details_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_details_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_dialog_element_interface_create_wrapper(void *interface) +{ + return lxb_html_dialog_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_dialog_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_dialog_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_directory_element_interface_create_wrapper(void *interface) +{ + return lxb_html_directory_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_directory_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_directory_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_div_element_interface_create_wrapper(void *interface) +{ + return lxb_html_div_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_div_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_div_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_d_list_element_interface_create_wrapper(void *interface) +{ + return lxb_html_d_list_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_d_list_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_d_list_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_embed_element_interface_create_wrapper(void *interface) +{ + return lxb_html_embed_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_embed_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_embed_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_field_set_element_interface_create_wrapper(void *interface) +{ + return lxb_html_field_set_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_field_set_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_field_set_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_font_element_interface_create_wrapper(void *interface) +{ + return lxb_html_font_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_font_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_font_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_form_element_interface_create_wrapper(void *interface) +{ + return lxb_html_form_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_form_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_form_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_frame_element_interface_create_wrapper(void *interface) +{ + return lxb_html_frame_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_frame_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_frame_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_frame_set_element_interface_create_wrapper(void *interface) +{ + return lxb_html_frame_set_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_frame_set_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_frame_set_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_heading_element_interface_create_wrapper(void *interface) +{ + return lxb_html_heading_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_heading_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_heading_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_head_element_interface_create_wrapper(void *interface) +{ + return lxb_html_head_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_head_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_head_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_hr_element_interface_create_wrapper(void *interface) +{ + return lxb_html_hr_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_hr_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_hr_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_html_element_interface_create_wrapper(void *interface) +{ + return lxb_html_html_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_html_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_html_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_iframe_element_interface_create_wrapper(void *interface) +{ + return lxb_html_iframe_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_iframe_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_iframe_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_image_element_interface_create_wrapper(void *interface) +{ + return lxb_html_image_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_image_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_image_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_input_element_interface_create_wrapper(void *interface) +{ + return lxb_html_input_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_input_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_input_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_label_element_interface_create_wrapper(void *interface) +{ + return lxb_html_label_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_label_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_label_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_legend_element_interface_create_wrapper(void *interface) +{ + return lxb_html_legend_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_legend_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_legend_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_li_element_interface_create_wrapper(void *interface) +{ + return lxb_html_li_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_li_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_li_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_link_element_interface_create_wrapper(void *interface) +{ + return lxb_html_link_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_link_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_link_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_pre_element_interface_create_wrapper(void *interface) +{ + return lxb_html_pre_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_pre_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_pre_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_map_element_interface_create_wrapper(void *interface) +{ + return lxb_html_map_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_map_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_map_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_marquee_element_interface_create_wrapper(void *interface) +{ + return lxb_html_marquee_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_marquee_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_marquee_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_menu_element_interface_create_wrapper(void *interface) +{ + return lxb_html_menu_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_menu_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_menu_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_meta_element_interface_create_wrapper(void *interface) +{ + return lxb_html_meta_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_meta_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_meta_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_meter_element_interface_create_wrapper(void *interface) +{ + return lxb_html_meter_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_meter_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_meter_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_object_element_interface_create_wrapper(void *interface) +{ + return lxb_html_object_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_object_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_object_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_o_list_element_interface_create_wrapper(void *interface) +{ + return lxb_html_o_list_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_o_list_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_o_list_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_opt_group_element_interface_create_wrapper(void *interface) +{ + return lxb_html_opt_group_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_opt_group_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_opt_group_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_option_element_interface_create_wrapper(void *interface) +{ + return lxb_html_option_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_option_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_option_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_output_element_interface_create_wrapper(void *interface) +{ + return lxb_html_output_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_output_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_output_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_paragraph_element_interface_create_wrapper(void *interface) +{ + return lxb_html_paragraph_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_paragraph_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_paragraph_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_param_element_interface_create_wrapper(void *interface) +{ + return lxb_html_param_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_param_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_param_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_picture_element_interface_create_wrapper(void *interface) +{ + return lxb_html_picture_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_picture_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_picture_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_progress_element_interface_create_wrapper(void *interface) +{ + return lxb_html_progress_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_progress_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_progress_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_script_element_interface_create_wrapper(void *interface) +{ + return lxb_html_script_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_script_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_script_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_select_element_interface_create_wrapper(void *interface) +{ + return lxb_html_select_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_select_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_select_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_slot_element_interface_create_wrapper(void *interface) +{ + return lxb_html_slot_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_slot_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_slot_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_source_element_interface_create_wrapper(void *interface) +{ + return lxb_html_source_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_source_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_source_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_span_element_interface_create_wrapper(void *interface) +{ + return lxb_html_span_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_span_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_span_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_style_element_interface_create_wrapper(void *interface) +{ + return lxb_html_style_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_style_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_style_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_table_element_interface_create_wrapper(void *interface) +{ + return lxb_html_table_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_table_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_table_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_table_section_element_interface_create_wrapper(void *interface) +{ + return lxb_html_table_section_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_table_section_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_table_section_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_table_cell_element_interface_create_wrapper(void *interface) +{ + return lxb_html_table_cell_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_table_cell_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_table_cell_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_template_element_interface_create_wrapper(void *interface) +{ + return lxb_html_template_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_template_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_template_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_text_area_element_interface_create_wrapper(void *interface) +{ + return lxb_html_text_area_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_text_area_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_text_area_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_time_element_interface_create_wrapper(void *interface) +{ + return lxb_html_time_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_time_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_time_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_title_element_interface_create_wrapper(void *interface) +{ + return lxb_html_title_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_title_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_title_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_table_row_element_interface_create_wrapper(void *interface) +{ + return lxb_html_table_row_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_table_row_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_table_row_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_track_element_interface_create_wrapper(void *interface) +{ + return lxb_html_track_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_track_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_track_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_u_list_element_interface_create_wrapper(void *interface) +{ + return lxb_html_u_list_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_u_list_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_u_list_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_video_element_interface_create_wrapper(void *interface) +{ + return lxb_html_video_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_video_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_video_element_interface_destroy(interface); +} + + #ifdef LXB_HTML_INTERFACE_RES_CONSTRUCTORS #ifndef LXB_HTML_INTERFACE_RES_CONSTRUCTORS_ENABLED #define LXB_HTML_INTERFACE_RES_CONSTRUCTORS_ENABLED @@ -125,2159 +1026,2159 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ { /* LXB_TAG__UNDEF */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG__END_OF_FILE */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG__TEXT */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_text_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_text_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_text_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_text_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_text_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_text_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG__DOCUMENT */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_document_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_document_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG__EM_COMMENT */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_comment_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_comment_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_comment_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_comment_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_comment_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_comment_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG__EM_DOCTYPE */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_document_type_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_document_type_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_A */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_anchor_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_anchor_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_ABBR */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_ACRONYM */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_ADDRESS */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_ALTGLYPH */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_ALTGLYPHDEF */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_ALTGLYPHITEM */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_ANIMATECOLOR */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_ANIMATEMOTION */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_ANIMATETRANSFORM */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_ANNOTATION_XML */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_APPLET */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_AREA */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_area_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_area_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_ARTICLE */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_ASIDE */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_AUDIO */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_audio_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_audio_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_B */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_BASE */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_base_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_base_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_BASEFONT */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_BDI */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_BDO */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_BGSOUND */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_BIG */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_BLINK */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_BLOCKQUOTE */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_quote_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_quote_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_BODY */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_body_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_body_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_BR */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_br_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_br_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_BUTTON */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_button_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_button_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_CANVAS */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_canvas_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_canvas_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_CAPTION */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_table_caption_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_table_caption_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_CENTER */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_CITE */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_CLIPPATH */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_CODE */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_COL */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_table_col_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_table_col_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_COLGROUP */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_table_col_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_table_col_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_DATA */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_data_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_data_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_DATALIST */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_data_list_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_data_list_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_DD */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_DEL */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_mod_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_mod_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_DESC */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_DETAILS */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_details_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_details_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_DFN */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_DIALOG */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_dialog_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_dialog_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_DIR */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_directory_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_directory_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_DIV */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_div_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_div_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_DL */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_d_list_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_d_list_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_DT */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_EM */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_EMBED */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_embed_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_embed_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_FEBLEND */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_FECOLORMATRIX */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_FECOMPONENTTRANSFER */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_FECOMPOSITE */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_FECONVOLVEMATRIX */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_FEDIFFUSELIGHTING */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_FEDISPLACEMENTMAP */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_FEDISTANTLIGHT */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_FEDROPSHADOW */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_FEFLOOD */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_FEFUNCA */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_FEFUNCB */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_FEFUNCG */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_FEFUNCR */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_FEGAUSSIANBLUR */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_FEIMAGE */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_FEMERGE */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_FEMERGENODE */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_FEMORPHOLOGY */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_FEOFFSET */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_FEPOINTLIGHT */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_FESPECULARLIGHTING */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_FESPOTLIGHT */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_FETILE */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_FETURBULENCE */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_FIELDSET */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_field_set_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_field_set_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_FIGCAPTION */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_FIGURE */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_FONT */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_font_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_font_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_FOOTER */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_FOREIGNOBJECT */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_FORM */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_form_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_form_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_FRAME */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_frame_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_frame_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_FRAMESET */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_frame_set_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_frame_set_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_GLYPHREF */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_H1 */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_heading_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_heading_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_H2 */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_heading_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_heading_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_H3 */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_heading_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_heading_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_H4 */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_heading_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_heading_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_H5 */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_heading_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_heading_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_H6 */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_heading_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_heading_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_HEAD */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_head_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_head_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_HEADER */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_HGROUP */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_HR */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_hr_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_hr_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_HTML */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_I */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_IFRAME */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_iframe_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_iframe_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_IMAGE */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_image_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_image_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_IMG */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_image_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_image_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_INPUT */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_input_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_input_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_INS */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_mod_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_mod_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_ISINDEX */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_KBD */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_KEYGEN */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_LABEL */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_label_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_label_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_LEGEND */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_legend_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_legend_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_LI */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_li_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_li_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_LINEARGRADIENT */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_LINK */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_link_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_link_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_LISTING */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_pre_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_pre_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_MAIN */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_MALIGNMARK */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_MAP */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_map_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_map_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_MARK */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_MARQUEE */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_marquee_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_marquee_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_MATH */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_MENU */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_menu_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_menu_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_META */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_meta_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_meta_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_METER */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_meter_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_meter_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_MFENCED */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_MGLYPH */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_MI */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_MN */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_MO */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_MS */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_MTEXT */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_MULTICOL */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_NAV */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_NEXTID */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_NOBR */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_NOEMBED */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_NOFRAMES */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_NOSCRIPT */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_OBJECT */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_object_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_object_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_OL */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_o_list_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_o_list_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_OPTGROUP */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_opt_group_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_opt_group_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_OPTION */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_option_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_option_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_OUTPUT */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_output_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_output_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_P */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_paragraph_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_paragraph_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_PARAM */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_param_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_param_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_PATH */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_PICTURE */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_picture_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_picture_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_PLAINTEXT */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_PRE */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_pre_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_pre_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_PROGRESS */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_progress_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_progress_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_Q */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_quote_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_quote_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_RADIALGRADIENT */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_RB */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_RP */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_RT */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_RTC */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_RUBY */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_S */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_SAMP */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_SCRIPT */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_script_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_script_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_SECTION */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_SELECT */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_select_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_select_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_SLOT */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_slot_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_slot_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_SMALL */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_SOURCE */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_source_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_source_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_SPACER */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_SPAN */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_span_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_span_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_STRIKE */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_STRONG */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_STYLE */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_style_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_style_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_SUB */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_SUMMARY */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_SUP */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_SVG */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_TABLE */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_table_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_table_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_TBODY */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_table_section_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_table_section_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_TD */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_table_cell_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_table_cell_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_TEMPLATE */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_template_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_template_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_TEXTAREA */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_text_area_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_text_area_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_TEXTPATH */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_TFOOT */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_table_section_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_table_section_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_TH */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_table_cell_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_table_cell_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_THEAD */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_table_section_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_table_section_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_TIME */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_time_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_time_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_TITLE */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_title_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_title_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_TR */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_table_row_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_table_row_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_TRACK */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_track_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_track_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_TT */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_U */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_UL */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_u_list_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_u_list_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_VAR */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_VIDEO */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_video_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_video_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_WBR */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_XMP */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_pre_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_pre_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper } }; #endif /* LXB_HTML_INTERFACE_RES_CONSTRUCTORS_ENABLED */ @@ -2290,2159 +3191,2159 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG { /* LXB_TAG__UNDEF */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG__END_OF_FILE */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG__TEXT */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_text_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_text_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_text_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_text_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_text_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_text_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG__DOCUMENT */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_document_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_document_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG__EM_COMMENT */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_comment_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_comment_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_comment_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_comment_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_comment_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_comment_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG__EM_DOCTYPE */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_document_type_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_document_type_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_A */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_anchor_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_anchor_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_ABBR */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_ACRONYM */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_ADDRESS */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_ALTGLYPH */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_ALTGLYPHDEF */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_ALTGLYPHITEM */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_ANIMATECOLOR */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_ANIMATEMOTION */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_ANIMATETRANSFORM */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_ANNOTATION_XML */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_APPLET */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_AREA */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_area_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_area_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_ARTICLE */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_ASIDE */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_AUDIO */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_audio_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_audio_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_B */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_BASE */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_base_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_base_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_BASEFONT */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_BDI */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_BDO */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_BGSOUND */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_BIG */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_BLINK */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_BLOCKQUOTE */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_quote_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_quote_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_BODY */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_body_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_body_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_BR */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_br_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_br_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_BUTTON */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_button_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_button_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_CANVAS */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_canvas_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_canvas_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_CAPTION */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_table_caption_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_table_caption_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_CENTER */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_CITE */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_CLIPPATH */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_CODE */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_COL */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_table_col_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_table_col_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_COLGROUP */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_table_col_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_table_col_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_DATA */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_data_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_data_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_DATALIST */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_data_list_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_data_list_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_DD */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_DEL */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_mod_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_mod_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_DESC */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_DETAILS */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_details_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_details_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_DFN */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_DIALOG */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_dialog_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_dialog_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_DIR */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_directory_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_directory_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_DIV */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_div_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_div_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_DL */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_d_list_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_d_list_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_DT */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_EM */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_EMBED */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_embed_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_embed_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_FEBLEND */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_FECOLORMATRIX */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_FECOMPONENTTRANSFER */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_FECOMPOSITE */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_FECONVOLVEMATRIX */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_FEDIFFUSELIGHTING */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_FEDISPLACEMENTMAP */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_FEDISTANTLIGHT */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_FEDROPSHADOW */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_FEFLOOD */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_FEFUNCA */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_FEFUNCB */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_FEFUNCG */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_FEFUNCR */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_FEGAUSSIANBLUR */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_FEIMAGE */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_FEMERGE */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_FEMERGENODE */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_FEMORPHOLOGY */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_FEOFFSET */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_FEPOINTLIGHT */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_FESPECULARLIGHTING */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_FESPOTLIGHT */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_FETILE */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_FETURBULENCE */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_FIELDSET */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_field_set_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_field_set_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_FIGCAPTION */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_FIGURE */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_FONT */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_font_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_font_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_FOOTER */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_FOREIGNOBJECT */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_FORM */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_form_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_form_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_FRAME */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_frame_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_frame_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_FRAMESET */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_frame_set_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_frame_set_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_GLYPHREF */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_H1 */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_heading_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_heading_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_H2 */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_heading_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_heading_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_H3 */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_heading_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_heading_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_H4 */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_heading_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_heading_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_H5 */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_heading_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_heading_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_H6 */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_heading_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_heading_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_HEAD */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_head_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_head_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_HEADER */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_HGROUP */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_HR */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_hr_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_hr_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_HTML */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_I */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_IFRAME */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_iframe_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_iframe_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_IMAGE */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_image_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_image_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_IMG */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_image_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_image_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_INPUT */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_input_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_input_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_INS */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_mod_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_mod_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_ISINDEX */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_KBD */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_KEYGEN */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_LABEL */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_label_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_label_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_LEGEND */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_legend_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_legend_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_LI */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_li_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_li_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_LINEARGRADIENT */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_LINK */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_link_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_link_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_LISTING */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_pre_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_pre_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_MAIN */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_MALIGNMARK */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_MAP */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_map_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_map_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_MARK */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_MARQUEE */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_marquee_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_marquee_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_MATH */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_MENU */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_menu_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_menu_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_META */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_meta_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_meta_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_METER */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_meter_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_meter_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_MFENCED */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_MGLYPH */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_MI */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_MN */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_MO */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_MS */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_MTEXT */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_MULTICOL */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_NAV */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_NEXTID */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_NOBR */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_NOEMBED */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_NOFRAMES */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_NOSCRIPT */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_OBJECT */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_object_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_object_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_OL */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_o_list_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_o_list_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_OPTGROUP */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_opt_group_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_opt_group_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_OPTION */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_option_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_option_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_OUTPUT */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_output_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_output_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_P */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_paragraph_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_paragraph_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_PARAM */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_param_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_param_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_PATH */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_PICTURE */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_picture_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_picture_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_PLAINTEXT */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_PRE */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_pre_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_pre_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_PROGRESS */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_progress_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_progress_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_Q */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_quote_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_quote_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_RADIALGRADIENT */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_RB */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_RP */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_RT */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_RTC */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_RUBY */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_S */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_SAMP */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_SCRIPT */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_script_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_script_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_SECTION */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_SELECT */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_select_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_select_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_SLOT */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_slot_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_slot_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_SMALL */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_SOURCE */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_source_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_source_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_SPACER */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_SPAN */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_span_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_span_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_STRIKE */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_STRONG */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_STYLE */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_style_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_style_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_SUB */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_SUMMARY */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_SUP */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_SVG */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_TABLE */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_table_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_table_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_TBODY */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_table_section_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_table_section_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_TD */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_table_cell_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_table_cell_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_TEMPLATE */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_template_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_template_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_TEXTAREA */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_text_area_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_text_area_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_TEXTPATH */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_TFOOT */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_table_section_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_table_section_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_TH */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_table_cell_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_table_cell_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_THEAD */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_table_section_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_table_section_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_TIME */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_time_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_time_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_TITLE */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_title_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_title_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_TR */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_table_row_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_table_row_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_TRACK */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_track_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_track_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_TT */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_U */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_UL */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_u_list_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_u_list_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_VAR */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_VIDEO */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_video_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_video_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_WBR */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_XMP */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_pre_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_pre_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper } }; #endif /* LXB_HTML_INTERFACE_RES_DESTRUCTOR_ENABLED */ diff --git a/ext/lexbor/lexbor/html/interfaces/document.c b/ext/lexbor/lexbor/html/interfaces/document.c index 48f8403a9e9..34a2c6db0e5 100644 --- a/ext/lexbor/lexbor/html/interfaces/document.c +++ b/ext/lexbor/lexbor/html/interfaces/document.c @@ -33,12 +33,19 @@ static lexbor_action_t lxb_html_document_title_walker(lxb_dom_node_t *node, void *ctx); +lxb_inline lxb_dom_interface_t * +lxb_html_document_interface_create_wrapper(lxb_dom_document_t *document, + lxb_tag_id_t tag_id, lxb_ns_id_t ns) +{ + return lxb_html_interface_create(lxb_html_interface_document(document), + tag_id, ns); +} + lxb_html_document_t * lxb_html_document_interface_create(lxb_html_document_t *document) { lxb_status_t status; lxb_dom_document_t *doc; - lxb_dom_interface_create_f icreator; if (document != NULL) { doc = lexbor_mraw_calloc(lxb_html_document_mraw(document), @@ -52,10 +59,9 @@ lxb_html_document_interface_create(lxb_html_document_t *document) return NULL; } - icreator = (lxb_dom_interface_create_f) lxb_html_interface_create; - status = lxb_dom_document_init(doc, lxb_dom_interface_document(document), - icreator, lxb_html_interface_clone, + lxb_html_document_interface_create_wrapper, + lxb_html_interface_clone, lxb_html_interface_destroy, LXB_DOM_DOCUMENT_DTYPE_HTML, LXB_NS_HTML); if (status != LXB_STATUS_OK) { diff --git a/ext/lexbor/lexbor/url/url.c b/ext/lexbor/lexbor/url/url.c index bbb3b5bbd3c..ed3732a5cca 100644 --- a/ext/lexbor/lexbor/url/url.c +++ b/ext/lexbor/lexbor/url/url.c @@ -1818,7 +1818,7 @@ again: } if (override_state == LXB_URL_STATE_HOSTNAME_STATE) { - lxb_url_parse_return(orig_data, buf, LXB_STATUS_OK); + lxb_url_parse_return(orig_data, buf, LXB_STATUS_ERROR); } status = lxb_url_host_parse(parser, begin, p, &url->host, diff --git a/ext/libxml/config.w32 b/ext/libxml/config.w32 index cc5f284dbc1..2362ea0c2ba 100644 --- a/ext/libxml/config.w32 +++ b/ext/libxml/config.w32 @@ -11,7 +11,7 @@ if (PHP_LIBXML == "yes") { if (GREP_HEADER("libxml/xmlversion.h", "#define\\s+LIBXML_VERSION\\s+(\\d+)", PHP_PHP_BUILD + "\\include\\libxml2") && +RegExp.$1 >= 20904) { - EXTENSION("libxml", "libxml.c mime_sniff.c", false /* never shared */, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); + EXTENSION("libxml", "libxml.c mime_sniff.c image_svg.c", false /* never shared */, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); AC_DEFINE("HAVE_LIBXML", 1, "Define to 1 if the PHP extension 'libxml' is available."); ADD_FLAG("CFLAGS_LIBXML", "/D LIBXML_STATIC /D LIBXML_STATIC_FOR_DLL /D HAVE_WIN32_THREADS "); if (!PHP_LIBXML_SHARED) { diff --git a/ext/libxml/config0.m4 b/ext/libxml/config0.m4 index 67ffa9a78ce..5b400751d1b 100644 --- a/ext/libxml/config0.m4 +++ b/ext/libxml/config0.m4 @@ -12,7 +12,7 @@ if test "$PHP_LIBXML" != "no"; then AC_DEFINE([HAVE_LIBXML], [1], [Define to 1 if the PHP extension 'libxml' is available.]) PHP_NEW_EXTENSION([libxml], - [libxml.c mime_sniff.c], + [libxml.c mime_sniff.c image_svg.c], [$ext_shared],, [-DZEND_ENABLE_STATIC_TSRMLS_CACHE=1]) PHP_INSTALL_HEADERS([ext/libxml], [php_libxml.h]) diff --git a/ext/libxml/image_svg.c b/ext/libxml/image_svg.c new file mode 100644 index 00000000000..091f7e28316 --- /dev/null +++ b/ext/libxml/image_svg.c @@ -0,0 +1,178 @@ +/* + +----------------------------------------------------------------------+ + | Copyright (c) The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | https://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Niels Dossche | + +----------------------------------------------------------------------+ + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" +#include "image_svg.h" +#include "php_libxml.h" + +#include "ext/standard/php_image.h" + +#include + +#ifdef HAVE_LIBXML + +static int svg_image_type_id; + +static int php_libxml_svg_stream_read(void *context, char *buffer, int len) +{ + return php_stream_read(context, buffer, len); +} + +/* Sanity check that the input only contains characters valid for a dimension (numbers with units, e.g. 5cm). + * This also protects the user against injecting XSS. + * Only accept [0-9]+[a-zA-Z]* */ +static bool php_libxml_parse_dimension(const xmlChar *input, const xmlChar **unit_position) +{ + if (!(*input >= '0' && *input <= '9')) { + return false; + } + + input++; + + while (*input) { + if (!(*input >= '0' && *input <= '9')) { + if ((*input >= 'a' && *input <= 'z') || (*input >= 'A' && *input <= 'Z')) { + break; + } + return false; + } + input++; + } + + *unit_position = input; + + while (*input) { + if (!((*input >= 'a' && *input <= 'z') || (*input >= 'A' && *input <= 'Z'))) { + return false; + } + input++; + } + + return true; +} + +zend_result php_libxml_svg_image_handle(php_stream *stream, struct php_gfxinfo **result) +{ + if (php_stream_rewind(stream)) { + return FAILURE; + } + + /* Early check before doing more expensive work */ + if (php_stream_getc(stream) != '<') { + return FAILURE; + } + + if (php_stream_rewind(stream)) { + return FAILURE; + } + + PHP_LIBXML_SANITIZE_GLOBALS(reader_for_stream); + xmlTextReaderPtr reader = xmlReaderForIO( + php_libxml_svg_stream_read, + NULL, + stream, + NULL, + NULL, + XML_PARSE_NOWARNING | XML_PARSE_NOERROR | XML_PARSE_NONET + ); + PHP_LIBXML_RESTORE_GLOBALS(reader_for_stream); + + if (!reader) { + return FAILURE; + } + + bool is_svg = false; + while (xmlTextReaderRead(reader) == 1) { + if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_ELEMENT) { + /* Root must be an svg element */ + const xmlChar *name = xmlTextReaderConstLocalName(reader); + if (!name || strcasecmp((const char *) name, "svg") != 0) { + break; + } + + xmlChar *width = xmlTextReaderGetAttribute(reader, BAD_CAST "width"); + xmlChar *height = xmlTextReaderGetAttribute(reader, BAD_CAST "height"); + const xmlChar *width_unit_position, *height_unit_position; + if (!width || !height + || !php_libxml_parse_dimension(width, &width_unit_position) + || !php_libxml_parse_dimension(height, &height_unit_position)) { + xmlFree(width); + xmlFree(height); + break; + } + + is_svg = true; + if (result) { + *result = ecalloc(1, sizeof(**result)); + (*result)->width = ZEND_STRTOL((const char *) width, NULL, 10); + (*result)->height = ZEND_STRTOL((const char *) height, NULL, 10); + if (*width_unit_position) { + (*result)->width_unit = zend_string_init((const char*) width_unit_position, + xmlStrlen(width_unit_position), false); + } + if (*height_unit_position) { + (*result)->height_unit = zend_string_init((const char*) height_unit_position, + xmlStrlen(height_unit_position), false); + } + } + + xmlFree(width); + xmlFree(height); + break; + } + } + + xmlFreeTextReader(reader); + + return is_svg ? SUCCESS : FAILURE; +} + +zend_result php_libxml_svg_image_identify(php_stream *stream) +{ + return php_libxml_svg_image_handle(stream, NULL); +} + +struct php_gfxinfo *php_libxml_svg_image_get_info(php_stream *stream) +{ + struct php_gfxinfo *result = NULL; + zend_result status = php_libxml_svg_image_handle(stream, &result); + ZEND_ASSERT((status == SUCCESS) == (result != NULL)); + return result; +} + +static const struct php_image_handler svg_image_handler = { + "image/svg+xml", + ".svg", + PHP_IMAGE_CONST_NAME("SVG"), + php_libxml_svg_image_identify, + php_libxml_svg_image_get_info, +}; + +void php_libxml_register_image_svg_handler(void) +{ + svg_image_type_id = php_image_register_handler(&svg_image_handler); +} + +zend_result php_libxml_unregister_image_svg_handler(void) +{ + return php_image_unregister_handler(svg_image_type_id); +} + +#endif diff --git a/ext/standard/php_smart_string_public.h b/ext/libxml/image_svg.h similarity index 77% rename from ext/standard/php_smart_string_public.h rename to ext/libxml/image_svg.h index 264723e28e1..d023334af36 100644 --- a/ext/standard/php_smart_string_public.h +++ b/ext/libxml/image_svg.h @@ -10,10 +10,16 @@ | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ - | Author: Sascha Schumann | - | Xinchen Hui | + | Authors: Niels Dossche | +----------------------------------------------------------------------+ */ -/* Header moved to Zend. This file is retained for BC. */ -#include "zend_smart_string_public.h" +#ifndef LIBXML_IMAGE_SVG +#define LIBXML_IMAGE_SVG + +#include "zend.h" + +void php_libxml_register_image_svg_handler(void); +zend_result php_libxml_unregister_image_svg_handler(void); + +#endif diff --git a/ext/libxml/libxml.c b/ext/libxml/libxml.c index 03a89c7aad5..2e75d697296 100644 --- a/ext/libxml/libxml.c +++ b/ext/libxml/libxml.c @@ -43,6 +43,7 @@ #endif #include "php_libxml.h" +#include "image_svg.h" #define PHP_LIBXML_LOADED_VERSION ((char *)xmlParserVersion) @@ -84,8 +85,14 @@ static zend_long php_libxml_default_dump_doc_to_file(const char *filename, xmlDo /* }}} */ +static const zend_module_dep libxml_deps[] = { + ZEND_MOD_REQUIRED("standard") + ZEND_MOD_END +}; + zend_module_entry libxml_module_entry = { - STANDARD_MODULE_HEADER, + STANDARD_MODULE_HEADER_EX, NULL, + libxml_deps, "libxml", /* extension name */ ext_functions, /* extension function list */ PHP_MINIT(libxml), /* extension-wide startup function */ @@ -335,7 +342,26 @@ PHP_LIBXML_API void php_libxml_node_free_list(xmlNodePtr node) if (ptr->_private) { const php_libxml_node_object *obj = ptr->_private; if (!obj->document || obj->document->class_type < PHP_LIBXML_CLASS_MODERN) { - xmlReconciliateNs(curnode->doc, curnode); + if (LIBXML_VERSION < 21300 && UNEXPECTED(curnode->doc == NULL)) { + /* xmlReconciliateNs() in these versions just uses the document for xmlNewReconciledNs(), + * which can create an oldNs xml namespace declaration via xmlSearchNs() -> xmlTreeEnsureXMLDecl(). */ + xmlDoc dummy; + memset(&dummy, 0, sizeof(dummy)); + dummy.type = XML_DOCUMENT_NODE; + curnode->doc = &dummy; + xmlReconciliateNs(curnode->doc, curnode); + curnode->doc = NULL; + + /* Append oldNs to current node's nsDef, which can be at most one node. */ + if (dummy.oldNs) { + ZEND_ASSERT(dummy.oldNs->next == NULL); + xmlNsPtr old = curnode->nsDef; + curnode->nsDef = dummy.oldNs; + dummy.oldNs->next = old; + } + } else { + xmlReconciliateNs(curnode->doc, curnode); + } } } } @@ -969,6 +995,8 @@ static PHP_MINIT_FUNCTION(libxml) xmlOutputBufferCreateFilenameDefault(php_libxml_output_buffer_create_filename); } + php_libxml_register_image_svg_handler(); + return SUCCESS; } @@ -1010,7 +1038,7 @@ static PHP_MSHUTDOWN_FUNCTION(libxml) } php_libxml_shutdown(); - return SUCCESS; + return php_libxml_unregister_image_svg_handler(); } static zend_result php_libxml_post_deactivate(void) diff --git a/ext/libxml/libxml_arginfo.h b/ext/libxml/libxml_arginfo.h index 40963d9f98d..1741b7fa986 100644 --- a/ext/libxml/libxml_arginfo.h +++ b/ext/libxml/libxml_arginfo.h @@ -90,10 +90,8 @@ static void register_libxml_symbols(int module_number) zend_attribute *attribute_Deprecated_func_libxml_disable_entity_loader_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "libxml_disable_entity_loader", sizeof("libxml_disable_entity_loader") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_func_libxml_disable_entity_loader_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_func_libxml_disable_entity_loader_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_libxml_disable_entity_loader_0_arg1; zend_string *attribute_Deprecated_func_libxml_disable_entity_loader_0_arg1_str = zend_string_init("as external entity loading is disabled by default", strlen("as external entity loading is disabled by default"), 1); - ZVAL_STR(&attribute_Deprecated_func_libxml_disable_entity_loader_0_arg1, attribute_Deprecated_func_libxml_disable_entity_loader_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_libxml_disable_entity_loader_0->args[1].value, &attribute_Deprecated_func_libxml_disable_entity_loader_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_libxml_disable_entity_loader_0->args[1].value, attribute_Deprecated_func_libxml_disable_entity_loader_0_arg1_str); attribute_Deprecated_func_libxml_disable_entity_loader_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); } diff --git a/ext/libxml/tests/image/getimagesize.phpt b/ext/libxml/tests/image/getimagesize.phpt new file mode 100644 index 00000000000..22c099395c3 --- /dev/null +++ b/ext/libxml/tests/image/getimagesize.phpt @@ -0,0 +1,98 @@ +--TEST-- +getimagesize() with svg input +--EXTENSIONS-- +libxml +--FILE-- +", + "svg width=\"1\" height=\"1\"", + << + + +XML, + "", + "", + "", + "", + "", + "", + "", + "", +]; + +foreach ($inputs as $input) { + var_dump(getimagesizefromstring($input)); +} + +?> +--EXPECTF-- +bool(false) +bool(false) +array(6) { + [0]=> + int(4) + [1]=> + int(8) + [2]=> + int(%d) + ["mime"]=> + string(13) "image/svg+xml" + ["width_unit"]=> + string(2) "cm" + ["height_unit"]=> + string(2) "cm" +} +array(7) { + [0]=> + int(1) + [1]=> + int(1) + [2]=> + int(%d) + [3]=> + string(20) "width="1" height="1"" + ["mime"]=> + string(13) "image/svg+xml" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" +} +array(7) { + [0]=> + int(1) + [1]=> + int(1) + [2]=> + int(%d) + [3]=> + string(20) "width="1" height="1"" + ["mime"]=> + string(13) "image/svg+xml" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" +} +array(6) { + [0]=> + int(1) + [1]=> + int(1) + [2]=> + int(%d) + ["mime"]=> + string(13) "image/svg+xml" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "mm" +} +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) diff --git a/ext/libxml/tests/image/imagetype_svg.phpt b/ext/libxml/tests/image/imagetype_svg.phpt new file mode 100644 index 00000000000..4115e6a1c89 --- /dev/null +++ b/ext/libxml/tests/image/imagetype_svg.phpt @@ -0,0 +1,16 @@ +--TEST-- +imagetype API with svg extension +--EXTENSIONS-- +libxml +--FILE-- + IMAGETYPE_SVG); +var_dump(image_type_to_extension(IMAGETYPE_SVG)); +var_dump(image_type_to_mime_type(IMAGETYPE_SVG)); + +?> +--EXPECT-- +bool(true) +string(4) ".svg" +string(13) "image/svg+xml" diff --git a/ext/libxml/tests/libxml_entity_loading_disabled_by_default.phpt b/ext/libxml/tests/libxml_entity_loading_disabled_by_default.phpt index 7a775474619..f1ab4fa8906 100644 --- a/ext/libxml/tests/libxml_entity_loading_disabled_by_default.phpt +++ b/ext/libxml/tests/libxml_entity_loading_disabled_by_default.phpt @@ -30,7 +30,6 @@ function parseXML2($xml) { function parseXML3($xml) { $p = xml_parser_create(); xml_parse_into_struct($p, $xml, $vals, $index); - xml_parser_free($p); return var_export($vals, true); } diff --git a/ext/mbstring/libmbfl/filters/mbfilter_cjk.c b/ext/mbstring/libmbfl/filters/mbfilter_cjk.c index bc14fe48f2c..716fec0c054 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_cjk.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_cjk.c @@ -21,15 +21,15 @@ * This macro converts uppercase ASCII values to Regional Indicator codepoints */ #define NFLAGS(c) (0x1F1A5+((unsigned int)(c))) -static const char nflags_s[10][2] = {"CN", "DE", "ES", "FR", "GB", "IT", "JP", "KR", "RU", "US"}; +static const char nflags_s[10][2] ZEND_NONSTRING = {"CN", "DE", "ES", "FR", "GB", "IT", "JP", "KR", "RU", "US"}; static const int nflags_code_kddi[10] = { 0x2549, 0x2546, 0x24C0, 0x2545, 0x2548, 0x2547, 0x2750, 0x254A, 0x24C1, 0x27F7 }; static const int nflags_code_sb[10] = { 0x2B0A, 0x2B05, 0x2B08, 0x2B04, 0x2B07, 0x2B06, 0x2B02, 0x2B0B, 0x2B09, 0x2B03 }; #define EMIT_KEYPAD_EMOJI(c) do { *snd = (c); return 0x20E3; } while(0) #define EMIT_FLAG_EMOJI(country) do { *snd = NFLAGS((country)[0]); return NFLAGS((country)[1]); } while(0) -static const char nflags_kddi[6][2] = {"FR", "DE", "IT", "GB", "CN", "KR"}; -static const char nflags_sb[10][2] = {"JP", "US", "FR", "DE", "IT", "GB", "ES", "RU", "CN", "KR"}; +static const char nflags_kddi[6][2] ZEND_NONSTRING = {"FR", "DE", "IT", "GB", "CN", "KR"}; +static const char nflags_sb[10][2] ZEND_NONSTRING = {"JP", "US", "FR", "DE", "IT", "GB", "ES", "RU", "CN", "KR"}; /* number -> (ku*94)+ten value for telephone keypad character */ #define DOCOMO_KEYPAD(n) ((n) == 0 ? 0x296F : (0x2965 + (n))) diff --git a/ext/mbstring/libmbfl/filters/mbfilter_utf8.c b/ext/mbstring/libmbfl/filters/mbfilter_utf8.c index 0786c8e7f31..41ffb97e58f 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_utf8.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_utf8.c @@ -725,7 +725,7 @@ static int mbfl_filt_conv_wchar_utf8_mobile(int c, mbfl_convert_filter *filter) * This macro converts uppercase ASCII values to Regional Indicator codepoints */ #define NFLAGS(c) (0x1F1A5+(int)(c)) -static const char nflags_s[10][2] = {"CN","DE","ES","FR","GB","IT","JP","KR","RU","US"}; +static const char nflags_s[10][2] ZEND_NONSTRING = {"CN","DE","ES","FR","GB","IT","JP","KR","RU","US"}; static const int nflags_code_kddi[10] = { 0x2549, 0x2546, 0x24C0, 0x2545, 0x2548, 0x2547, 0x2750, 0x254A, 0x24C1, 0x27F7 }; static const int nflags_code_sb[10] = { 0x2B0A, 0x2B05, 0x2B08, 0x2B04, 0x2B07, 0x2B06, 0x2B02, 0x2B0B, 0x2B09, 0x2B03 }; diff --git a/ext/mbstring/mbstring.c b/ext/mbstring/mbstring.c index 9c1759f05db..4044f4de9ff 100644 --- a/ext/mbstring/mbstring.c +++ b/ext/mbstring/mbstring.c @@ -1160,8 +1160,8 @@ PHP_RSHUTDOWN_FUNCTION(mbstring) MBSTRG(outconv_state) = 0; if (MBSTRG(all_encodings_list)) { - GC_DELREF(MBSTRG(all_encodings_list)); - zend_array_destroy(MBSTRG(all_encodings_list)); + /* must be *array* release to remove from GC root buffer and free the hashtable itself */ + zend_array_release(MBSTRG(all_encodings_list)); MBSTRG(all_encodings_list) = NULL; } @@ -4506,7 +4506,7 @@ PHP_FUNCTION(mb_send_mail) ZEND_PARSE_PARAMETERS_END(); if (str_headers) { - if (strlen(ZSTR_VAL(str_headers)) != ZSTR_LEN(str_headers)) { + if (UNEXPECTED(zend_str_has_nul_byte(str_headers))) { zend_argument_value_error(4, "must not contain any null bytes"); RETURN_THROWS(); } diff --git a/ext/mbstring/tests/gh19397.phpt b/ext/mbstring/tests/gh19397.phpt new file mode 100644 index 00000000000..e6e07b161c0 --- /dev/null +++ b/ext/mbstring/tests/gh19397.phpt @@ -0,0 +1,11 @@ +--TEST-- +GH-19397 (mb_list_encodings() can cause crashes on shutdown) +--EXTENSIONS-- +mbstring +--FILE-- + 0); +?> +--EXPECT-- +bool(true) diff --git a/ext/mysqli/mysqli.stub.php b/ext/mysqli/mysqli.stub.php index 06db6ac2686..89c499ba8aa 100644 --- a/ext/mysqli/mysqli.stub.php +++ b/ext/mysqli/mysqli.stub.php @@ -1383,6 +1383,7 @@ function mysqli_error_list(mysqli $mysql): array {} function mysqli_stmt_execute(mysqli_stmt $statement, ?array $params = null): bool {} /** @alias mysqli_stmt_execute */ +#[\Deprecated(since: '8.5', message: "use mysqli_stmt_execute() instead")] function mysqli_execute(mysqli_stmt $statement, ?array $params = null): bool {} function mysqli_execute_query(mysqli $mysql, string $query, ?array $params = null): mysqli_result|bool {} diff --git a/ext/mysqli/mysqli_arginfo.h b/ext/mysqli/mysqli_arginfo.h index a0871cb9883..52497844fb1 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: 2547f63fd024fd5f4fecc574bbcff1301d1d36e5 */ + * Stub hash: ce02f0eeb9191e7c92cb8a5e5fcae20fceb0b47c */ 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) @@ -837,7 +837,7 @@ static const zend_function_entry ext_functions[] = { ZEND_FE(mysqli_error, arginfo_mysqli_error) ZEND_FE(mysqli_error_list, arginfo_mysqli_error_list) ZEND_FE(mysqli_stmt_execute, arginfo_mysqli_stmt_execute) - ZEND_RAW_FENTRY("mysqli_execute", zif_mysqli_stmt_execute, arginfo_mysqli_execute, 0, NULL, NULL) + ZEND_RAW_FENTRY("mysqli_execute", zif_mysqli_stmt_execute, arginfo_mysqli_execute, ZEND_ACC_DEPRECATED, NULL, NULL) ZEND_FE(mysqli_execute_query, arginfo_mysqli_execute_query) ZEND_FE(mysqli_fetch_field, arginfo_mysqli_fetch_field) ZEND_FE(mysqli_fetch_fields, arginfo_mysqli_fetch_fields) @@ -1150,22 +1150,25 @@ static void register_mysqli_symbols(int module_number) zend_add_parameter_attribute(zend_hash_str_find_ptr(CG(function_table), "mysqli_connect", sizeof("mysqli_connect") - 1), 2, ZSTR_KNOWN(ZEND_STR_SENSITIVEPARAMETER), 0); + zend_attribute *attribute_Deprecated_func_mysqli_execute_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "mysqli_execute", sizeof("mysqli_execute") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + ZVAL_STR(&attribute_Deprecated_func_mysqli_execute_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_5)); + attribute_Deprecated_func_mysqli_execute_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zend_string *attribute_Deprecated_func_mysqli_execute_0_arg1_str = zend_string_init("use mysqli_stmt_execute() instead", strlen("use mysqli_stmt_execute() instead"), 1); + ZVAL_STR(&attribute_Deprecated_func_mysqli_execute_0->args[1].value, attribute_Deprecated_func_mysqli_execute_0_arg1_str); + attribute_Deprecated_func_mysqli_execute_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + zend_attribute *attribute_Deprecated_func_mysqli_kill_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "mysqli_kill", sizeof("mysqli_kill") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_func_mysqli_kill_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_4)); attribute_Deprecated_func_mysqli_kill_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_mysqli_kill_0_arg1; zend_string *attribute_Deprecated_func_mysqli_kill_0_arg1_str = zend_string_init("use KILL CONNECTION/QUERY SQL statement instead", strlen("use KILL CONNECTION/QUERY SQL statement instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_mysqli_kill_0_arg1, attribute_Deprecated_func_mysqli_kill_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_mysqli_kill_0->args[1].value, &attribute_Deprecated_func_mysqli_kill_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_mysqli_kill_0->args[1].value, attribute_Deprecated_func_mysqli_kill_0_arg1_str); attribute_Deprecated_func_mysqli_kill_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_func_mysqli_ping_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "mysqli_ping", sizeof("mysqli_ping") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_func_mysqli_ping_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_4)); attribute_Deprecated_func_mysqli_ping_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_mysqli_ping_0_arg1; zend_string *attribute_Deprecated_func_mysqli_ping_0_arg1_str = zend_string_init("because the reconnect feature has been removed in PHP 8.2 and this function is now redundant", strlen("because the reconnect feature has been removed in PHP 8.2 and this function is now redundant"), 1); - ZVAL_STR(&attribute_Deprecated_func_mysqli_ping_0_arg1, attribute_Deprecated_func_mysqli_ping_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_mysqli_ping_0->args[1].value, &attribute_Deprecated_func_mysqli_ping_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_mysqli_ping_0->args[1].value, attribute_Deprecated_func_mysqli_ping_0_arg1_str); attribute_Deprecated_func_mysqli_ping_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_add_parameter_attribute(zend_hash_str_find_ptr(CG(function_table), "mysqli_real_connect", sizeof("mysqli_real_connect") - 1), 3, ZSTR_KNOWN(ZEND_STR_SENSITIVEPARAMETER), 0); @@ -1173,172 +1176,120 @@ static void register_mysqli_symbols(int module_number) zend_attribute *attribute_Deprecated_func_mysqli_refresh_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "mysqli_refresh", sizeof("mysqli_refresh") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_func_mysqli_refresh_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_4)); attribute_Deprecated_func_mysqli_refresh_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_mysqli_refresh_0_arg1; zend_string *attribute_Deprecated_func_mysqli_refresh_0_arg1_str = zend_string_init("use FLUSH SQL statement instead", strlen("use FLUSH SQL statement instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_mysqli_refresh_0_arg1, attribute_Deprecated_func_mysqli_refresh_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_mysqli_refresh_0->args[1].value, &attribute_Deprecated_func_mysqli_refresh_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_mysqli_refresh_0->args[1].value, attribute_Deprecated_func_mysqli_refresh_0_arg1_str); attribute_Deprecated_func_mysqli_refresh_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_const_MYSQLI_STORE_RESULT_COPY_DATA_0 = zend_add_global_constant_attribute(const_MYSQLI_STORE_RESULT_COPY_DATA, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_const_MYSQLI_STORE_RESULT_COPY_DATA_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_4)); attribute_Deprecated_const_MYSQLI_STORE_RESULT_COPY_DATA_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_const_MYSQLI_STORE_RESULT_COPY_DATA_0_arg1; zend_string *attribute_Deprecated_const_MYSQLI_STORE_RESULT_COPY_DATA_0_arg1_str = zend_string_init("as the mysqli_store_result() parameter is unused since 8.1", strlen("as the mysqli_store_result() parameter is unused since 8.1"), 1); - ZVAL_STR(&attribute_Deprecated_const_MYSQLI_STORE_RESULT_COPY_DATA_0_arg1, attribute_Deprecated_const_MYSQLI_STORE_RESULT_COPY_DATA_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_const_MYSQLI_STORE_RESULT_COPY_DATA_0->args[1].value, &attribute_Deprecated_const_MYSQLI_STORE_RESULT_COPY_DATA_0_arg1); + ZVAL_STR(&attribute_Deprecated_const_MYSQLI_STORE_RESULT_COPY_DATA_0->args[1].value, attribute_Deprecated_const_MYSQLI_STORE_RESULT_COPY_DATA_0_arg1_str); attribute_Deprecated_const_MYSQLI_STORE_RESULT_COPY_DATA_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_const_MYSQLI_NO_DATA_0 = zend_add_global_constant_attribute(const_MYSQLI_NO_DATA, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_const_MYSQLI_NO_DATA_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_1)); attribute_Deprecated_const_MYSQLI_NO_DATA_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_const_MYSQLI_NO_DATA_0_arg1; zend_string *attribute_Deprecated_const_MYSQLI_NO_DATA_0_arg1_str = zend_string_init("as it was unused", strlen("as it was unused"), 1); - ZVAL_STR(&attribute_Deprecated_const_MYSQLI_NO_DATA_0_arg1, attribute_Deprecated_const_MYSQLI_NO_DATA_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_const_MYSQLI_NO_DATA_0->args[1].value, &attribute_Deprecated_const_MYSQLI_NO_DATA_0_arg1); + ZVAL_STR(&attribute_Deprecated_const_MYSQLI_NO_DATA_0->args[1].value, attribute_Deprecated_const_MYSQLI_NO_DATA_0_arg1_str); attribute_Deprecated_const_MYSQLI_NO_DATA_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_const_MYSQLI_DATA_TRUNCATED_0 = zend_add_global_constant_attribute(const_MYSQLI_DATA_TRUNCATED, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_const_MYSQLI_DATA_TRUNCATED_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_1)); attribute_Deprecated_const_MYSQLI_DATA_TRUNCATED_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_const_MYSQLI_DATA_TRUNCATED_0_arg1; - zend_string *attribute_Deprecated_const_MYSQLI_DATA_TRUNCATED_0_arg1_str = zend_string_init("as it was unused", strlen("as it was unused"), 1); - ZVAL_STR(&attribute_Deprecated_const_MYSQLI_DATA_TRUNCATED_0_arg1, attribute_Deprecated_const_MYSQLI_DATA_TRUNCATED_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_const_MYSQLI_DATA_TRUNCATED_0->args[1].value, &attribute_Deprecated_const_MYSQLI_DATA_TRUNCATED_0_arg1); + ZVAL_STR_COPY(&attribute_Deprecated_const_MYSQLI_DATA_TRUNCATED_0->args[1].value, attribute_Deprecated_const_MYSQLI_NO_DATA_0_arg1_str); attribute_Deprecated_const_MYSQLI_DATA_TRUNCATED_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_const_MYSQLI_SERVER_QUERY_NO_GOOD_INDEX_USED_0 = zend_add_global_constant_attribute(const_MYSQLI_SERVER_QUERY_NO_GOOD_INDEX_USED, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_const_MYSQLI_SERVER_QUERY_NO_GOOD_INDEX_USED_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_1)); attribute_Deprecated_const_MYSQLI_SERVER_QUERY_NO_GOOD_INDEX_USED_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_const_MYSQLI_SERVER_QUERY_NO_GOOD_INDEX_USED_0_arg1; - zend_string *attribute_Deprecated_const_MYSQLI_SERVER_QUERY_NO_GOOD_INDEX_USED_0_arg1_str = zend_string_init("as it was unused", strlen("as it was unused"), 1); - ZVAL_STR(&attribute_Deprecated_const_MYSQLI_SERVER_QUERY_NO_GOOD_INDEX_USED_0_arg1, attribute_Deprecated_const_MYSQLI_SERVER_QUERY_NO_GOOD_INDEX_USED_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_const_MYSQLI_SERVER_QUERY_NO_GOOD_INDEX_USED_0->args[1].value, &attribute_Deprecated_const_MYSQLI_SERVER_QUERY_NO_GOOD_INDEX_USED_0_arg1); + ZVAL_STR_COPY(&attribute_Deprecated_const_MYSQLI_SERVER_QUERY_NO_GOOD_INDEX_USED_0->args[1].value, attribute_Deprecated_const_MYSQLI_NO_DATA_0_arg1_str); attribute_Deprecated_const_MYSQLI_SERVER_QUERY_NO_GOOD_INDEX_USED_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_const_MYSQLI_SERVER_QUERY_NO_INDEX_USED_0 = zend_add_global_constant_attribute(const_MYSQLI_SERVER_QUERY_NO_INDEX_USED, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_const_MYSQLI_SERVER_QUERY_NO_INDEX_USED_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_1)); attribute_Deprecated_const_MYSQLI_SERVER_QUERY_NO_INDEX_USED_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_const_MYSQLI_SERVER_QUERY_NO_INDEX_USED_0_arg1; - zend_string *attribute_Deprecated_const_MYSQLI_SERVER_QUERY_NO_INDEX_USED_0_arg1_str = zend_string_init("as it was unused", strlen("as it was unused"), 1); - ZVAL_STR(&attribute_Deprecated_const_MYSQLI_SERVER_QUERY_NO_INDEX_USED_0_arg1, attribute_Deprecated_const_MYSQLI_SERVER_QUERY_NO_INDEX_USED_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_const_MYSQLI_SERVER_QUERY_NO_INDEX_USED_0->args[1].value, &attribute_Deprecated_const_MYSQLI_SERVER_QUERY_NO_INDEX_USED_0_arg1); + ZVAL_STR_COPY(&attribute_Deprecated_const_MYSQLI_SERVER_QUERY_NO_INDEX_USED_0->args[1].value, attribute_Deprecated_const_MYSQLI_NO_DATA_0_arg1_str); attribute_Deprecated_const_MYSQLI_SERVER_QUERY_NO_INDEX_USED_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_const_MYSQLI_SERVER_QUERY_WAS_SLOW_0 = zend_add_global_constant_attribute(const_MYSQLI_SERVER_QUERY_WAS_SLOW, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_const_MYSQLI_SERVER_QUERY_WAS_SLOW_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_1)); attribute_Deprecated_const_MYSQLI_SERVER_QUERY_WAS_SLOW_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_const_MYSQLI_SERVER_QUERY_WAS_SLOW_0_arg1; - zend_string *attribute_Deprecated_const_MYSQLI_SERVER_QUERY_WAS_SLOW_0_arg1_str = zend_string_init("as it was unused", strlen("as it was unused"), 1); - ZVAL_STR(&attribute_Deprecated_const_MYSQLI_SERVER_QUERY_WAS_SLOW_0_arg1, attribute_Deprecated_const_MYSQLI_SERVER_QUERY_WAS_SLOW_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_const_MYSQLI_SERVER_QUERY_WAS_SLOW_0->args[1].value, &attribute_Deprecated_const_MYSQLI_SERVER_QUERY_WAS_SLOW_0_arg1); + ZVAL_STR_COPY(&attribute_Deprecated_const_MYSQLI_SERVER_QUERY_WAS_SLOW_0->args[1].value, attribute_Deprecated_const_MYSQLI_NO_DATA_0_arg1_str); attribute_Deprecated_const_MYSQLI_SERVER_QUERY_WAS_SLOW_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_const_MYSQLI_SERVER_PS_OUT_PARAMS_0 = zend_add_global_constant_attribute(const_MYSQLI_SERVER_PS_OUT_PARAMS, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_const_MYSQLI_SERVER_PS_OUT_PARAMS_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_1)); attribute_Deprecated_const_MYSQLI_SERVER_PS_OUT_PARAMS_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_const_MYSQLI_SERVER_PS_OUT_PARAMS_0_arg1; - zend_string *attribute_Deprecated_const_MYSQLI_SERVER_PS_OUT_PARAMS_0_arg1_str = zend_string_init("as it was unused", strlen("as it was unused"), 1); - ZVAL_STR(&attribute_Deprecated_const_MYSQLI_SERVER_PS_OUT_PARAMS_0_arg1, attribute_Deprecated_const_MYSQLI_SERVER_PS_OUT_PARAMS_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_const_MYSQLI_SERVER_PS_OUT_PARAMS_0->args[1].value, &attribute_Deprecated_const_MYSQLI_SERVER_PS_OUT_PARAMS_0_arg1); + ZVAL_STR_COPY(&attribute_Deprecated_const_MYSQLI_SERVER_PS_OUT_PARAMS_0->args[1].value, attribute_Deprecated_const_MYSQLI_NO_DATA_0_arg1_str); attribute_Deprecated_const_MYSQLI_SERVER_PS_OUT_PARAMS_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_const_MYSQLI_REFRESH_GRANT_0 = zend_add_global_constant_attribute(const_MYSQLI_REFRESH_GRANT, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_const_MYSQLI_REFRESH_GRANT_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_4)); attribute_Deprecated_const_MYSQLI_REFRESH_GRANT_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_const_MYSQLI_REFRESH_GRANT_0_arg1; zend_string *attribute_Deprecated_const_MYSQLI_REFRESH_GRANT_0_arg1_str = zend_string_init("as mysqli_refresh() is deprecated", strlen("as mysqli_refresh() is deprecated"), 1); - ZVAL_STR(&attribute_Deprecated_const_MYSQLI_REFRESH_GRANT_0_arg1, attribute_Deprecated_const_MYSQLI_REFRESH_GRANT_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_const_MYSQLI_REFRESH_GRANT_0->args[1].value, &attribute_Deprecated_const_MYSQLI_REFRESH_GRANT_0_arg1); + ZVAL_STR(&attribute_Deprecated_const_MYSQLI_REFRESH_GRANT_0->args[1].value, attribute_Deprecated_const_MYSQLI_REFRESH_GRANT_0_arg1_str); attribute_Deprecated_const_MYSQLI_REFRESH_GRANT_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_const_MYSQLI_REFRESH_LOG_0 = zend_add_global_constant_attribute(const_MYSQLI_REFRESH_LOG, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_const_MYSQLI_REFRESH_LOG_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_4)); attribute_Deprecated_const_MYSQLI_REFRESH_LOG_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_const_MYSQLI_REFRESH_LOG_0_arg1; - zend_string *attribute_Deprecated_const_MYSQLI_REFRESH_LOG_0_arg1_str = zend_string_init("as mysqli_refresh() is deprecated", strlen("as mysqli_refresh() is deprecated"), 1); - ZVAL_STR(&attribute_Deprecated_const_MYSQLI_REFRESH_LOG_0_arg1, attribute_Deprecated_const_MYSQLI_REFRESH_LOG_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_const_MYSQLI_REFRESH_LOG_0->args[1].value, &attribute_Deprecated_const_MYSQLI_REFRESH_LOG_0_arg1); + ZVAL_STR_COPY(&attribute_Deprecated_const_MYSQLI_REFRESH_LOG_0->args[1].value, attribute_Deprecated_const_MYSQLI_REFRESH_GRANT_0_arg1_str); attribute_Deprecated_const_MYSQLI_REFRESH_LOG_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_const_MYSQLI_REFRESH_TABLES_0 = zend_add_global_constant_attribute(const_MYSQLI_REFRESH_TABLES, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_const_MYSQLI_REFRESH_TABLES_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_4)); attribute_Deprecated_const_MYSQLI_REFRESH_TABLES_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_const_MYSQLI_REFRESH_TABLES_0_arg1; - zend_string *attribute_Deprecated_const_MYSQLI_REFRESH_TABLES_0_arg1_str = zend_string_init("as mysqli_refresh() is deprecated", strlen("as mysqli_refresh() is deprecated"), 1); - ZVAL_STR(&attribute_Deprecated_const_MYSQLI_REFRESH_TABLES_0_arg1, attribute_Deprecated_const_MYSQLI_REFRESH_TABLES_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_const_MYSQLI_REFRESH_TABLES_0->args[1].value, &attribute_Deprecated_const_MYSQLI_REFRESH_TABLES_0_arg1); + ZVAL_STR_COPY(&attribute_Deprecated_const_MYSQLI_REFRESH_TABLES_0->args[1].value, attribute_Deprecated_const_MYSQLI_REFRESH_GRANT_0_arg1_str); attribute_Deprecated_const_MYSQLI_REFRESH_TABLES_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_const_MYSQLI_REFRESH_HOSTS_0 = zend_add_global_constant_attribute(const_MYSQLI_REFRESH_HOSTS, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_const_MYSQLI_REFRESH_HOSTS_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_4)); attribute_Deprecated_const_MYSQLI_REFRESH_HOSTS_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_const_MYSQLI_REFRESH_HOSTS_0_arg1; - zend_string *attribute_Deprecated_const_MYSQLI_REFRESH_HOSTS_0_arg1_str = zend_string_init("as mysqli_refresh() is deprecated", strlen("as mysqli_refresh() is deprecated"), 1); - ZVAL_STR(&attribute_Deprecated_const_MYSQLI_REFRESH_HOSTS_0_arg1, attribute_Deprecated_const_MYSQLI_REFRESH_HOSTS_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_const_MYSQLI_REFRESH_HOSTS_0->args[1].value, &attribute_Deprecated_const_MYSQLI_REFRESH_HOSTS_0_arg1); + ZVAL_STR_COPY(&attribute_Deprecated_const_MYSQLI_REFRESH_HOSTS_0->args[1].value, attribute_Deprecated_const_MYSQLI_REFRESH_GRANT_0_arg1_str); attribute_Deprecated_const_MYSQLI_REFRESH_HOSTS_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_const_MYSQLI_REFRESH_STATUS_0 = zend_add_global_constant_attribute(const_MYSQLI_REFRESH_STATUS, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_const_MYSQLI_REFRESH_STATUS_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_4)); attribute_Deprecated_const_MYSQLI_REFRESH_STATUS_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_const_MYSQLI_REFRESH_STATUS_0_arg1; - zend_string *attribute_Deprecated_const_MYSQLI_REFRESH_STATUS_0_arg1_str = zend_string_init("as mysqli_refresh() is deprecated", strlen("as mysqli_refresh() is deprecated"), 1); - ZVAL_STR(&attribute_Deprecated_const_MYSQLI_REFRESH_STATUS_0_arg1, attribute_Deprecated_const_MYSQLI_REFRESH_STATUS_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_const_MYSQLI_REFRESH_STATUS_0->args[1].value, &attribute_Deprecated_const_MYSQLI_REFRESH_STATUS_0_arg1); + ZVAL_STR_COPY(&attribute_Deprecated_const_MYSQLI_REFRESH_STATUS_0->args[1].value, attribute_Deprecated_const_MYSQLI_REFRESH_GRANT_0_arg1_str); attribute_Deprecated_const_MYSQLI_REFRESH_STATUS_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_const_MYSQLI_REFRESH_THREADS_0 = zend_add_global_constant_attribute(const_MYSQLI_REFRESH_THREADS, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_const_MYSQLI_REFRESH_THREADS_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_4)); attribute_Deprecated_const_MYSQLI_REFRESH_THREADS_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_const_MYSQLI_REFRESH_THREADS_0_arg1; - zend_string *attribute_Deprecated_const_MYSQLI_REFRESH_THREADS_0_arg1_str = zend_string_init("as mysqli_refresh() is deprecated", strlen("as mysqli_refresh() is deprecated"), 1); - ZVAL_STR(&attribute_Deprecated_const_MYSQLI_REFRESH_THREADS_0_arg1, attribute_Deprecated_const_MYSQLI_REFRESH_THREADS_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_const_MYSQLI_REFRESH_THREADS_0->args[1].value, &attribute_Deprecated_const_MYSQLI_REFRESH_THREADS_0_arg1); + ZVAL_STR_COPY(&attribute_Deprecated_const_MYSQLI_REFRESH_THREADS_0->args[1].value, attribute_Deprecated_const_MYSQLI_REFRESH_GRANT_0_arg1_str); attribute_Deprecated_const_MYSQLI_REFRESH_THREADS_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_const_MYSQLI_REFRESH_REPLICA_0 = zend_add_global_constant_attribute(const_MYSQLI_REFRESH_REPLICA, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_const_MYSQLI_REFRESH_REPLICA_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_4)); attribute_Deprecated_const_MYSQLI_REFRESH_REPLICA_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_const_MYSQLI_REFRESH_REPLICA_0_arg1; - zend_string *attribute_Deprecated_const_MYSQLI_REFRESH_REPLICA_0_arg1_str = zend_string_init("as mysqli_refresh() is deprecated", strlen("as mysqli_refresh() is deprecated"), 1); - ZVAL_STR(&attribute_Deprecated_const_MYSQLI_REFRESH_REPLICA_0_arg1, attribute_Deprecated_const_MYSQLI_REFRESH_REPLICA_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_const_MYSQLI_REFRESH_REPLICA_0->args[1].value, &attribute_Deprecated_const_MYSQLI_REFRESH_REPLICA_0_arg1); + ZVAL_STR_COPY(&attribute_Deprecated_const_MYSQLI_REFRESH_REPLICA_0->args[1].value, attribute_Deprecated_const_MYSQLI_REFRESH_GRANT_0_arg1_str); attribute_Deprecated_const_MYSQLI_REFRESH_REPLICA_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_const_MYSQLI_REFRESH_SLAVE_0 = zend_add_global_constant_attribute(const_MYSQLI_REFRESH_SLAVE, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_const_MYSQLI_REFRESH_SLAVE_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_4)); attribute_Deprecated_const_MYSQLI_REFRESH_SLAVE_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_const_MYSQLI_REFRESH_SLAVE_0_arg1; - zend_string *attribute_Deprecated_const_MYSQLI_REFRESH_SLAVE_0_arg1_str = zend_string_init("as mysqli_refresh() is deprecated", strlen("as mysqli_refresh() is deprecated"), 1); - ZVAL_STR(&attribute_Deprecated_const_MYSQLI_REFRESH_SLAVE_0_arg1, attribute_Deprecated_const_MYSQLI_REFRESH_SLAVE_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_const_MYSQLI_REFRESH_SLAVE_0->args[1].value, &attribute_Deprecated_const_MYSQLI_REFRESH_SLAVE_0_arg1); + ZVAL_STR_COPY(&attribute_Deprecated_const_MYSQLI_REFRESH_SLAVE_0->args[1].value, attribute_Deprecated_const_MYSQLI_REFRESH_GRANT_0_arg1_str); attribute_Deprecated_const_MYSQLI_REFRESH_SLAVE_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_const_MYSQLI_REFRESH_MASTER_0 = zend_add_global_constant_attribute(const_MYSQLI_REFRESH_MASTER, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_const_MYSQLI_REFRESH_MASTER_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_4)); attribute_Deprecated_const_MYSQLI_REFRESH_MASTER_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_const_MYSQLI_REFRESH_MASTER_0_arg1; - zend_string *attribute_Deprecated_const_MYSQLI_REFRESH_MASTER_0_arg1_str = zend_string_init("as mysqli_refresh() is deprecated", strlen("as mysqli_refresh() is deprecated"), 1); - ZVAL_STR(&attribute_Deprecated_const_MYSQLI_REFRESH_MASTER_0_arg1, attribute_Deprecated_const_MYSQLI_REFRESH_MASTER_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_const_MYSQLI_REFRESH_MASTER_0->args[1].value, &attribute_Deprecated_const_MYSQLI_REFRESH_MASTER_0_arg1); + ZVAL_STR_COPY(&attribute_Deprecated_const_MYSQLI_REFRESH_MASTER_0->args[1].value, attribute_Deprecated_const_MYSQLI_REFRESH_GRANT_0_arg1_str); attribute_Deprecated_const_MYSQLI_REFRESH_MASTER_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_const_MYSQLI_REFRESH_BACKUP_LOG_0 = zend_add_global_constant_attribute(const_MYSQLI_REFRESH_BACKUP_LOG, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_const_MYSQLI_REFRESH_BACKUP_LOG_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_4)); attribute_Deprecated_const_MYSQLI_REFRESH_BACKUP_LOG_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_const_MYSQLI_REFRESH_BACKUP_LOG_0_arg1; - zend_string *attribute_Deprecated_const_MYSQLI_REFRESH_BACKUP_LOG_0_arg1_str = zend_string_init("as mysqli_refresh() is deprecated", strlen("as mysqli_refresh() is deprecated"), 1); - ZVAL_STR(&attribute_Deprecated_const_MYSQLI_REFRESH_BACKUP_LOG_0_arg1, attribute_Deprecated_const_MYSQLI_REFRESH_BACKUP_LOG_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_const_MYSQLI_REFRESH_BACKUP_LOG_0->args[1].value, &attribute_Deprecated_const_MYSQLI_REFRESH_BACKUP_LOG_0_arg1); + ZVAL_STR_COPY(&attribute_Deprecated_const_MYSQLI_REFRESH_BACKUP_LOG_0->args[1].value, attribute_Deprecated_const_MYSQLI_REFRESH_GRANT_0_arg1_str); attribute_Deprecated_const_MYSQLI_REFRESH_BACKUP_LOG_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_const_MYSQLI_IS_MARIADB_0 = zend_add_global_constant_attribute(const_MYSQLI_IS_MARIADB, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_const_MYSQLI_IS_MARIADB_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_2)); attribute_Deprecated_const_MYSQLI_IS_MARIADB_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_const_MYSQLI_IS_MARIADB_0_arg1; zend_string *attribute_Deprecated_const_MYSQLI_IS_MARIADB_0_arg1_str = zend_string_init("as it is always false", strlen("as it is always false"), 1); - ZVAL_STR(&attribute_Deprecated_const_MYSQLI_IS_MARIADB_0_arg1, attribute_Deprecated_const_MYSQLI_IS_MARIADB_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_const_MYSQLI_IS_MARIADB_0->args[1].value, &attribute_Deprecated_const_MYSQLI_IS_MARIADB_0_arg1); + ZVAL_STR(&attribute_Deprecated_const_MYSQLI_IS_MARIADB_0->args[1].value, attribute_Deprecated_const_MYSQLI_IS_MARIADB_0_arg1_str); attribute_Deprecated_const_MYSQLI_IS_MARIADB_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); } @@ -1501,37 +1452,29 @@ static zend_class_entry *register_class_mysqli(void) zend_attribute *attribute_Deprecated_func_get_client_info_0 = zend_add_function_attribute(zend_hash_str_find_ptr(&class_entry->function_table, "get_client_info", sizeof("get_client_info") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_func_get_client_info_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_1)); attribute_Deprecated_func_get_client_info_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_get_client_info_0_arg1; zend_string *attribute_Deprecated_func_get_client_info_0_arg1_str = zend_string_init("use mysqli_get_client_info() instead", strlen("use mysqli_get_client_info() instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_get_client_info_0_arg1, attribute_Deprecated_func_get_client_info_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_get_client_info_0->args[1].value, &attribute_Deprecated_func_get_client_info_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_get_client_info_0->args[1].value, attribute_Deprecated_func_get_client_info_0_arg1_str); attribute_Deprecated_func_get_client_info_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_func_init_0 = zend_add_function_attribute(zend_hash_str_find_ptr(&class_entry->function_table, "init", sizeof("init") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_func_init_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_1)); attribute_Deprecated_func_init_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_init_0_arg1; zend_string *attribute_Deprecated_func_init_0_arg1_str = zend_string_init("replace calls to parent::init() with parent::__construct()", strlen("replace calls to parent::init() with parent::__construct()"), 1); - ZVAL_STR(&attribute_Deprecated_func_init_0_arg1, attribute_Deprecated_func_init_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_init_0->args[1].value, &attribute_Deprecated_func_init_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_init_0->args[1].value, attribute_Deprecated_func_init_0_arg1_str); attribute_Deprecated_func_init_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_func_kill_0 = zend_add_function_attribute(zend_hash_str_find_ptr(&class_entry->function_table, "kill", sizeof("kill") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_func_kill_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_4)); attribute_Deprecated_func_kill_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_kill_0_arg1; zend_string *attribute_Deprecated_func_kill_0_arg1_str = zend_string_init("use KILL CONNECTION/QUERY SQL statement instead", strlen("use KILL CONNECTION/QUERY SQL statement instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_kill_0_arg1, attribute_Deprecated_func_kill_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_kill_0->args[1].value, &attribute_Deprecated_func_kill_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_kill_0->args[1].value, attribute_Deprecated_func_kill_0_arg1_str); attribute_Deprecated_func_kill_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_func_ping_0 = zend_add_function_attribute(zend_hash_str_find_ptr(&class_entry->function_table, "ping", sizeof("ping") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_func_ping_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_4)); attribute_Deprecated_func_ping_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_ping_0_arg1; zend_string *attribute_Deprecated_func_ping_0_arg1_str = zend_string_init("because the reconnect feature has been removed in PHP 8.2 and this method is now redundant", strlen("because the reconnect feature has been removed in PHP 8.2 and this method is now redundant"), 1); - ZVAL_STR(&attribute_Deprecated_func_ping_0_arg1, attribute_Deprecated_func_ping_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_ping_0->args[1].value, &attribute_Deprecated_func_ping_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_ping_0->args[1].value, attribute_Deprecated_func_ping_0_arg1_str); attribute_Deprecated_func_ping_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_add_parameter_attribute(zend_hash_str_find_ptr(&class_entry->function_table, "real_connect", sizeof("real_connect") - 1), 2, ZSTR_KNOWN(ZEND_STR_SENSITIVEPARAMETER), 0); @@ -1539,10 +1482,8 @@ static zend_class_entry *register_class_mysqli(void) zend_attribute *attribute_Deprecated_func_refresh_0 = zend_add_function_attribute(zend_hash_str_find_ptr(&class_entry->function_table, "refresh", sizeof("refresh") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_func_refresh_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_4)); attribute_Deprecated_func_refresh_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_refresh_0_arg1; zend_string *attribute_Deprecated_func_refresh_0_arg1_str = zend_string_init("use FLUSH SQL statement instead", strlen("use FLUSH SQL statement instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_refresh_0_arg1, attribute_Deprecated_func_refresh_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_refresh_0->args[1].value, &attribute_Deprecated_func_refresh_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_refresh_0->args[1].value, attribute_Deprecated_func_refresh_0_arg1_str); attribute_Deprecated_func_refresh_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); return class_entry; diff --git a/ext/odbc/config.m4 b/ext/odbc/config.m4 index 9baa8dbd8e6..4a1a4bb2133 100644 --- a/ext/odbc/config.m4 +++ b/ext/odbc/config.m4 @@ -106,13 +106,6 @@ dnl dnl configure options dnl -PHP_ARG_WITH([odbcver],, - [AS_HELP_STRING([[--with-odbcver[=HEX]]], - [Force support for the passed ODBC version. A hex number is expected, - default 0x0350. Use the special value of 0 to prevent an explicit ODBCVER to - be defined.])], - [0x0350]) - AS_VAR_IF([ODBC_TYPE],, [ PHP_ARG_WITH([adabas], [for Adabas support], @@ -410,12 +403,6 @@ PHP_ARG_WITH([dbmaker], ]) ]) -AH_TEMPLATE([ODBCVER], [The highest supported ODBC version.]) -AS_VAR_IF([PHP_ODBCVER], [no], - [AC_DEFINE([ODBCVER], [0x0350])], - [AS_VAR_IF([PHP_ODBCVER], [0],, - [AC_DEFINE_UNQUOTED([ODBCVER], [$PHP_ODBCVER])])]) - dnl Extension setup if test -n "$ODBC_TYPE"; then AS_VAR_IF([ODBC_TYPE], [dbmaker],, [ diff --git a/ext/odbc/config.w32 b/ext/odbc/config.w32 index 1030db44465..e19013c0fc4 100644 --- a/ext/odbc/config.w32 +++ b/ext/odbc/config.w32 @@ -1,7 +1,6 @@ // vim:ft=javascript ARG_ENABLE("odbc", "ODBC support", "no"); -ARG_WITH("odbcver", "Force support for the passed ODBC version. A hex number is expected, default 0x0350. Use the special value of 0 to prevent an explicit ODBCVER to be defined.", "0x0350"); if (PHP_ODBC == "yes") { if (CHECK_LIB("odbc32.lib", "odbc") && CHECK_LIB("odbccp32.lib", "odbc") @@ -10,11 +9,6 @@ if (PHP_ODBC == "yes") { EXTENSION("odbc", "php_odbc.c odbc_utils.c", PHP_ODBC_SHARED, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); AC_DEFINE("HAVE_UODBC", 1, "Define to 1 if the PHP extension 'odbc' is available."); AC_DEFINE("HAVE_SQLDATASOURCES", 1, "Define to 1 if ODBC library has 'SQLDataSources', as a function or macro."); - if ("no" == PHP_ODBCVER) { - AC_DEFINE("ODBCVER", "0x0350", "The highest supported ODBC version.", false); - } else if ("0" != PHP_ODBCVER) { - AC_DEFINE("ODBCVER", PHP_ODBCVER, "The highest supported ODBC version.", false); - } } else { WARNING("odbc support can't be enabled, libraries or header are missing (SDK)") PHP_ODBC = "no" diff --git a/ext/odbc/odbc.stub.php b/ext/odbc/odbc.stub.php index 8a54e913e88..9c942cca1bc 100644 --- a/ext/odbc/odbc.stub.php +++ b/ext/odbc/odbc.stub.php @@ -233,8 +233,6 @@ namespace { * @cvalue SQL_TIMESTAMP */ const SQL_TIMESTAMP = UNKNOWN; - -#if (defined(ODBCVER) && (ODBCVER >= 0x0300)) /** * @var int * @cvalue SQL_TYPE_DATE @@ -327,8 +325,6 @@ namespace { */ const SQL_QUICK = UNKNOWN; -#endif - function odbc_close_all(): void {} function odbc_binmode(Odbc\Result $statement, int $mode): true {} diff --git a/ext/odbc/odbc_arginfo.h b/ext/odbc/odbc_arginfo.h index ddb6b35ab1a..da588a452a7 100644 --- a/ext/odbc/odbc_arginfo.h +++ b/ext/odbc/odbc_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: efd913e4fcacb2949dc5392857032ab9c59c818d */ + * Stub hash: 2a788e343c154d2f29adeab45d5507f73de1b6bf */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_odbc_close_all, 0, 0, IS_VOID, 0) ZEND_END_ARG_INFO() @@ -408,7 +408,6 @@ static void register_odbc_symbols(int module_number) REGISTER_LONG_CONSTANT("SQL_DATE", SQL_DATE, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("SQL_TIME", SQL_TIME, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("SQL_TIMESTAMP", SQL_TIMESTAMP, CONST_PERSISTENT); -#if (defined(ODBCVER) && (ODBCVER >= 0x0300)) REGISTER_LONG_CONSTANT("SQL_TYPE_DATE", SQL_TYPE_DATE, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("SQL_TYPE_TIME", SQL_TYPE_TIME, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("SQL_TYPE_TIMESTAMP", SQL_TYPE_TIMESTAMP, CONST_PERSISTENT); @@ -426,7 +425,6 @@ static void register_odbc_symbols(int module_number) REGISTER_LONG_CONSTANT("SQL_INDEX_ALL", SQL_INDEX_ALL, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("SQL_ENSURE", SQL_ENSURE, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("SQL_QUICK", SQL_QUICK, CONST_PERSISTENT); -#endif zend_attribute *attribute_Deprecated_func_odbc_result_all_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "odbc_result_all", sizeof("odbc_result_all") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 1); diff --git a/ext/odbc/php_odbc.c b/ext/odbc/php_odbc.c index 7bc3a8bc17d..80e2ac9359d 100644 --- a/ext/odbc/php_odbc.c +++ b/ext/odbc/php_odbc.c @@ -346,21 +346,21 @@ static void _close_odbc_pconn(zend_resource *rsrc) /* {{{ PHP_INI_DISP(display_link_nums) */ static PHP_INI_DISP(display_link_nums) { - char *value; + const zend_string *value; if (type == PHP_INI_DISPLAY_ORIG && ini_entry->modified) { - value = ZSTR_VAL(ini_entry->orig_value); + value = ini_entry->orig_value; } else if (ini_entry->value) { - value = ZSTR_VAL(ini_entry->value); + value = ini_entry->value; } else { value = NULL; } if (value) { - if (atoi(value) == -1) { + if (atoi(ZSTR_VAL(value)) == -1) { PUTS("Unlimited"); } else { - php_printf("%s", value); + php_output_write(ZSTR_VAL(value), ZSTR_LEN(value)); } } } @@ -579,10 +579,6 @@ PHP_MINFO_FUNCTION(odbc) snprintf(buf, sizeof(buf), ZEND_LONG_FMT, ODBCG(num_links)); php_info_print_table_row(2, "Active Links", buf); php_info_print_table_row(2, "ODBC library", PHP_ODBC_TYPE); -#ifdef ODBCVER - snprintf(buf, sizeof(buf), "0x%.4x", ODBCVER); - php_info_print_table_row(2, "ODBCVER", buf); -#endif #ifndef PHP_WIN32 php_info_print_table_row(2, "ODBC_CFLAGS", PHP_ODBC_CFLAGS); php_info_print_table_row(2, "ODBC_LFLAGS", PHP_ODBC_LFLAGS); @@ -670,7 +666,6 @@ void odbc_bindcols(odbc_result *result) SQLSMALLINT colnamelen; /* Not used */ SQLLEN displaysize; SQLUSMALLINT colfieldid; - int charextraalloc; result->values = (odbc_result_value *) safe_emalloc(sizeof(odbc_result_value), result->numcols, 0); @@ -678,13 +673,13 @@ void odbc_bindcols(odbc_result *result) result->binmode = ODBCG(defaultbinmode); for(i = 0; i < result->numcols; i++) { - charextraalloc = 0; + bool char_extra_alloc = false; colfieldid = SQL_COLUMN_DISPLAY_SIZE; - rc = PHP_ODBC_SQLCOLATTRIBUTE(result->stmt, (SQLUSMALLINT)(i+1), PHP_ODBC_SQL_DESC_NAME, + rc = SQLColAttribute(result->stmt, (SQLUSMALLINT)(i+1), SQL_DESC_NAME, result->values[i].name, sizeof(result->values[i].name), &colnamelen, 0); result->values[i].coltype = 0; - rc = PHP_ODBC_SQLCOLATTRIBUTE(result->stmt, (SQLUSMALLINT)(i+1), SQL_COLUMN_TYPE, + rc = SQLColAttribute(result->stmt, (SQLUSMALLINT)(i+1), SQL_COLUMN_TYPE, NULL, 0, NULL, &result->values[i].coltype); /* Don't bind LONG / BINARY columns, so that fetch behaviour can @@ -696,9 +691,7 @@ void odbc_bindcols(odbc_result *result) case SQL_VARBINARY: case SQL_LONGVARBINARY: case SQL_LONGVARCHAR: -#if defined(ODBCVER) && (ODBCVER >= 0x0300) case SQL_WLONGVARCHAR: -#endif result->values[i].value = NULL; break; @@ -711,22 +704,17 @@ void odbc_bindcols(odbc_result *result) #endif /* HAVE_ADABAS */ case SQL_CHAR: case SQL_VARCHAR: -#if defined(ODBCVER) && (ODBCVER >= 0x0300) case SQL_WCHAR: case SQL_WVARCHAR: colfieldid = SQL_DESC_OCTET_LENGTH; -#else - charextraalloc = 1; -#endif /* TODO: Check this is the intended behaviour */ ZEND_FALLTHROUGH; default: - rc = PHP_ODBC_SQLCOLATTRIBUTE(result->stmt, (SQLUSMALLINT)(i+1), colfieldid, + rc = SQLColAttribute(result->stmt, (SQLUSMALLINT)(i+1), colfieldid, NULL, 0, NULL, &displaysize); if (rc != SQL_SUCCESS) { displaysize = 0; } -#if defined(ODBCVER) && (ODBCVER >= 0x0300) if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO && colfieldid == SQL_DESC_OCTET_LENGTH) { SQLINTEGER err; SQLCHAR errtxt[128]; @@ -742,7 +730,7 @@ void odbc_bindcols(odbc_result *result) } /* This is a quirk for ODBC 2.0 compatibility for broken driver implementations. */ - charextraalloc = 1; + char_extra_alloc = true; rc = SQLColAttributes(result->stmt, (SQLUSMALLINT)(i+1), SQL_COLUMN_DISPLAY_SIZE, NULL, 0, NULL, &displaysize); if (rc != SQL_SUCCESS) { @@ -756,7 +744,6 @@ void odbc_bindcols(odbc_result *result) result->values[i].value = NULL; break; } -#endif /* Workaround for drivers that report VARCHAR(MAX) columns as SQL_VARCHAR (bug #73725) */ if (SQL_VARCHAR == result->values[i].coltype && displaysize == 0) { result->values[i].coltype = SQL_LONGVARCHAR; @@ -769,7 +756,7 @@ void odbc_bindcols(odbc_result *result) displaysize += 3; } - if (charextraalloc) { + if (char_extra_alloc) { /* Since we don't know the exact # of bytes, allocate extra */ displaysize *= 4; } @@ -845,7 +832,7 @@ void odbc_column_lengths(INTERNAL_FUNCTION_PARAMETERS, int type) RETURN_FALSE; } - PHP_ODBC_SQLCOLATTRIBUTE(result->stmt, (SQLUSMALLINT)pv_num, (SQLUSMALLINT) (type?SQL_COLUMN_SCALE:SQL_COLUMN_PRECISION), NULL, 0, NULL, &len); + SQLColAttribute(result->stmt, (SQLUSMALLINT)pv_num, (SQLUSMALLINT) (type?SQL_COLUMN_SCALE:SQL_COLUMN_PRECISION), NULL, 0, NULL, &len); RETURN_LONG(len); } @@ -916,7 +903,7 @@ PHP_FUNCTION(odbc_prepare) result->numparams = 0; result->param_info = NULL; - rc = PHP_ODBC_SQLALLOCSTMT(conn->hdbc, &(result->stmt)); + rc = SQLAllocHandle(SQL_HANDLE_STMT, conn->hdbc, &(result->stmt)); if (rc == SQL_INVALID_HANDLE) { php_error_docref(NULL, E_WARNING, "SQLAllocStmt error 'Invalid Handle'"); zval_ptr_dtor(return_value); @@ -938,7 +925,7 @@ PHP_FUNCTION(odbc_prepare) /* Try to set CURSOR_TYPE to dynamic. Driver will replace this with other type if not possible. */ - SQLSetStmtOption(result->stmt, SQL_CURSOR_TYPE, ODBCG(default_cursortype)); + SQLSetStmtAttr(result->stmt, SQL_ATTR_CURSOR_TYPE, (SQLPOINTER) ODBCG(default_cursortype), 0); } } else { result->fetch_abs = 0; @@ -1015,10 +1002,9 @@ PHP_FUNCTION(odbc_execute) zval *pv_res, *tmp; HashTable *pv_param_ht = (HashTable *) &zend_empty_array; odbc_params_t *params = NULL; - char *filename; SQLSMALLINT ctype; odbc_result *result; - int i, ne; + int i; RETCODE rc; if (zend_parse_parameters(ZEND_NUM_ARGS(), "O|h", &pv_res, odbc_result_ce, &pv_param_ht) == FAILURE) { @@ -1029,8 +1015,9 @@ PHP_FUNCTION(odbc_execute) CHECK_ODBC_RESULT(result); if (result->numparams > 0) { - if ((ne = zend_hash_num_elements(pv_param_ht)) < result->numparams) { - php_error_docref(NULL, E_WARNING, "Not enough parameters (%d should be %d) given", ne, result->numparams); + uint32_t ne = zend_hash_num_elements(pv_param_ht); + if (ne < result->numparams) { + php_error_docref(NULL, E_WARNING, "Not enough parameters (%" PRIu32 " should be %d) given", ne, result->numparams); RETURN_FALSE; } @@ -1063,11 +1050,11 @@ PHP_FUNCTION(odbc_execute) ZSTR_VAL(tmpstr)[0] == '\'' && ZSTR_VAL(tmpstr)[ZSTR_LEN(tmpstr) - 1] == '\'') { - if (ZSTR_LEN(tmpstr) != strlen(ZSTR_VAL(tmpstr))) { + if (UNEXPECTED(zend_str_has_nul_byte(tmpstr))) { odbc_release_params(result, params); RETURN_FALSE; } - filename = estrndup(&ZSTR_VAL(tmpstr)[1], ZSTR_LEN(tmpstr) - 2); + char *filename = estrndup(&ZSTR_VAL(tmpstr)[1], ZSTR_LEN(tmpstr) - 2); /* Check the basedir */ if (php_check_open_basedir(filename)) { @@ -1303,7 +1290,7 @@ PHP_FUNCTION(odbc_exec) object_init_ex(return_value, odbc_result_ce); result = Z_ODBC_RESULT_P(return_value); - rc = PHP_ODBC_SQLALLOCSTMT(conn->hdbc, &(result->stmt)); + rc = SQLAllocHandle(SQL_HANDLE_STMT, conn->hdbc, &(result->stmt)); if (rc == SQL_INVALID_HANDLE) { php_error_docref(NULL, E_WARNING, "SQLAllocStmt error 'Invalid Handle'"); zval_ptr_dtor(return_value); @@ -1325,7 +1312,7 @@ PHP_FUNCTION(odbc_exec) /* Try to set CURSOR_TYPE to dynamic. Driver will replace this with other type if not possible. */ - SQLSetStmtOption(result->stmt, SQL_CURSOR_TYPE, ODBCG(default_cursortype)); + SQLSetStmtAttr(result->stmt, SQL_ATTR_CURSOR_TYPE, (SQLPOINTER) ODBCG(default_cursortype), 0); } } else { result->fetch_abs = 0; @@ -1445,9 +1432,7 @@ static void php_odbc_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, int result_type) } ZEND_FALLTHROUGH; case SQL_LONGVARCHAR: -#if defined(ODBCVER) && (ODBCVER >= 0x0300) case SQL_WLONGVARCHAR: -#endif if (IS_SQL_LONG(result->values[i].coltype) && result->longreadlen <= 0) { ZVAL_EMPTY_STRING(&tmp); break; @@ -1615,9 +1600,7 @@ PHP_FUNCTION(odbc_fetch_into) /* TODO: Check this is the intended behaviour */ ZEND_FALLTHROUGH; case SQL_LONGVARCHAR: -#if defined(ODBCVER) && (ODBCVER >= 0x0300) case SQL_WLONGVARCHAR: -#endif if (IS_SQL_LONG(result->values[i].coltype) && result->longreadlen <= 0) { ZVAL_EMPTY_STRING(&tmp); break; @@ -1839,9 +1822,7 @@ PHP_FUNCTION(odbc_result) ZEND_FALLTHROUGH; case SQL_LONGVARCHAR: -#if defined(ODBCVER) && (ODBCVER >= 0x0300) case SQL_WLONGVARCHAR: -#endif if (IS_SQL_LONG(result->values[field_ind].coltype)) { if (result->longreadlen <= 0) { break; @@ -1849,7 +1830,7 @@ PHP_FUNCTION(odbc_result) fieldsize = result->longreadlen; } } else { - PHP_ODBC_SQLCOLATTRIBUTE(result->stmt, (SQLUSMALLINT)(field_ind + 1), + SQLColAttribute(result->stmt, (SQLUSMALLINT)(field_ind + 1), (SQLUSMALLINT)((sql_c_type == SQL_C_BINARY) ? SQL_COLUMN_LENGTH : SQL_COLUMN_DISPLAY_SIZE), NULL, 0, NULL, &fieldsize); @@ -1885,10 +1866,7 @@ PHP_FUNCTION(odbc_result) /* Reduce fieldlen by 1 if we have char data. One day we might have binary strings... */ if ((result->values[field_ind].coltype == SQL_LONGVARCHAR) -#if defined(ODBCVER) && (ODBCVER >= 0x0300) - || (result->values[field_ind].coltype == SQL_WLONGVARCHAR) -#endif - ) { + || (result->values[field_ind].coltype == SQL_WLONGVARCHAR)) { fieldsize -= 1; } /* Don't duplicate result, saves one emalloc. @@ -2024,9 +2002,7 @@ PHP_FUNCTION(odbc_result_all) /* TODO: Check this is the intended behaviour */ ZEND_FALLTHROUGH; case SQL_LONGVARCHAR: -#if defined(ODBCVER) && (ODBCVER >= 0x0300) case SQL_WLONGVARCHAR: -#endif if (IS_SQL_LONG(result->values[i].coltype) && result->longreadlen <= 0) { php_printf("Not printable"); @@ -2170,7 +2146,7 @@ bool odbc_sqlconnect(zval *zv, char *db, char *uid, char *pwd, int cur_opt, bool } #else if (cur_opt != SQL_CUR_DEFAULT) { - rc = SQLSetConnectOption(link->connection->hdbc, SQL_ODBC_CURSORS, cur_opt); + rc = SQLSetConnectAttr(link->connection->hdbc, SQL_ATTR_ODBC_CURSORS, (SQLPOINTER) (intptr_t) cur_opt, 0); if (rc != SQL_SUCCESS) { /* && rc != SQL_SUCCESS_WITH_INFO ? */ odbc_sql_error(link->connection, SQL_NULL_HSTMT, "SQLSetConnectOption"); return false; @@ -2185,8 +2161,7 @@ bool odbc_sqlconnect(zval *zv, char *db, char *uid, char *pwd, int cur_opt, bool int direct = 0; SQLCHAR dsnbuf[1024]; short dsnbuflen; - char *ldb = 0; - int ldb_len = 0; + char *ldb = NULL; /* a connection string may have = but not ; - i.e. "DSN=PHP" */ if (strstr((char*)db, "=")) { @@ -2248,7 +2223,7 @@ bool odbc_sqlconnect(zval *zv, char *db, char *uid, char *pwd, int cur_opt, bool efree(pwd_quoted); } } else { - ldb_len = strlen(db)+1; + size_t ldb_len = strlen(db)+1; ldb = (char*) emalloc(ldb_len); memcpy(ldb, db, ldb_len); } @@ -2602,7 +2577,7 @@ PHP_FUNCTION(odbc_field_type) RETURN_FALSE; } - PHP_ODBC_SQLCOLATTRIBUTE(result->stmt, (SQLUSMALLINT)pv_num, SQL_COLUMN_TYPE_NAME, tmp, 31, &tmplen, NULL); + SQLColAttribute(result->stmt, (SQLUSMALLINT)pv_num, SQL_COLUMN_TYPE_NAME, tmp, 31, &tmplen, NULL); RETURN_STRING(tmp); } /* }}} */ @@ -2672,7 +2647,7 @@ PHP_FUNCTION(odbc_autocommit) CHECK_ODBC_CONNECTION(conn); if (!pv_onoff_is_null) { - rc = SQLSetConnectOption(conn->hdbc, SQL_AUTOCOMMIT, pv_onoff ? SQL_AUTOCOMMIT_ON : SQL_AUTOCOMMIT_OFF); + rc = SQLSetConnectAttr(conn->hdbc, SQL_ATTR_AUTOCOMMIT, (SQLPOINTER) (intptr_t) (pv_onoff ? SQL_AUTOCOMMIT_ON : SQL_AUTOCOMMIT_OFF), 0); if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { odbc_sql_error(conn, SQL_NULL_HSTMT, "Set autocommit"); RETURN_FALSE; @@ -2681,7 +2656,7 @@ PHP_FUNCTION(odbc_autocommit) } else { SQLINTEGER status; - rc = SQLGetConnectOption(conn->hdbc, SQL_AUTOCOMMIT, (PTR)&status); + rc = SQLGetConnectAttr(conn->hdbc, SQL_ATTR_AUTOCOMMIT, &status, SQL_IS_INTEGER, NULL); if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { odbc_sql_error(conn, SQL_NULL_HSTMT, "Get commit status"); RETURN_FALSE; @@ -2783,7 +2758,7 @@ PHP_FUNCTION(odbc_setoption) php_error_docref(NULL, E_WARNING, "Unable to set option for persistent connection"); RETURN_FALSE; } - rc = SQLSetConnectOption(link->connection->hdbc, (unsigned short) pv_opt, pv_val); + rc = SQLSetConnectAttr(link->connection->hdbc, pv_opt, (SQLPOINTER) pv_val, 0); if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { odbc_sql_error(link->connection, SQL_NULL_HSTMT, "SetConnectOption"); RETURN_FALSE; @@ -2797,7 +2772,7 @@ PHP_FUNCTION(odbc_setoption) result = Z_ODBC_RESULT_P(pv_handle); CHECK_ODBC_RESULT(result); - rc = SQLSetStmtOption(result->stmt, (unsigned short) pv_opt, pv_val); + rc = SQLSetStmtAttr(result->stmt, pv_opt, (SQLPOINTER) pv_val, 0); if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { odbc_sql_error(result->conn_ptr, result->stmt, "SetStmtOption"); @@ -2837,7 +2812,7 @@ PHP_FUNCTION(odbc_tables) object_init_ex(return_value, odbc_result_ce); result = Z_ODBC_RESULT_P(return_value); - rc = PHP_ODBC_SQLALLOCSTMT(conn->hdbc, &(result->stmt)); + rc = SQLAllocHandle(SQL_HANDLE_STMT, conn->hdbc, &(result->stmt)); if (rc == SQL_INVALID_HANDLE) { php_error_docref(NULL, E_WARNING, "SQLAllocStmt error 'Invalid Handle'"); zval_ptr_dtor(return_value); @@ -2902,7 +2877,7 @@ PHP_FUNCTION(odbc_columns) object_init_ex(return_value, odbc_result_ce); result = Z_ODBC_RESULT_P(return_value); - rc = PHP_ODBC_SQLALLOCSTMT(conn->hdbc, &(result->stmt)); + rc = SQLAllocHandle(SQL_HANDLE_STMT, conn->hdbc, &(result->stmt)); if (rc == SQL_INVALID_HANDLE) { php_error_docref(NULL, E_WARNING, "SQLAllocStmt error 'Invalid Handle'"); zval_ptr_dtor(return_value); @@ -2970,7 +2945,7 @@ PHP_FUNCTION(odbc_columnprivileges) object_init_ex(return_value, odbc_result_ce); result = Z_ODBC_RESULT_P(return_value); - rc = PHP_ODBC_SQLALLOCSTMT(conn->hdbc, &(result->stmt)); + rc = SQLAllocHandle(SQL_HANDLE_STMT, conn->hdbc, &(result->stmt)); if (rc == SQL_INVALID_HANDLE) { php_error_docref(NULL, E_WARNING, "SQLAllocStmt error 'Invalid Handle'"); zval_ptr_dtor(return_value); @@ -3044,7 +3019,7 @@ PHP_FUNCTION(odbc_foreignkeys) object_init_ex(return_value, odbc_result_ce); result = Z_ODBC_RESULT_P(return_value); - rc = PHP_ODBC_SQLALLOCSTMT(conn->hdbc, &(result->stmt)); + rc = SQLAllocHandle(SQL_HANDLE_STMT, conn->hdbc, &(result->stmt)); if (rc == SQL_INVALID_HANDLE) { php_error_docref(NULL, E_WARNING, "SQLAllocStmt error 'Invalid Handle'"); zval_ptr_dtor(return_value); @@ -3108,7 +3083,7 @@ PHP_FUNCTION(odbc_gettypeinfo) object_init_ex(return_value, odbc_result_ce); result = Z_ODBC_RESULT_P(return_value); - rc = PHP_ODBC_SQLALLOCSTMT(conn->hdbc, &(result->stmt)); + rc = SQLAllocHandle(SQL_HANDLE_STMT, conn->hdbc, &(result->stmt)); if (rc == SQL_INVALID_HANDLE) { php_error_docref(NULL, E_WARNING, "SQLAllocStmt error 'Invalid Handle'"); zval_ptr_dtor(return_value); @@ -3163,7 +3138,7 @@ PHP_FUNCTION(odbc_primarykeys) object_init_ex(return_value, odbc_result_ce); result = Z_ODBC_RESULT_P(return_value); - rc = PHP_ODBC_SQLALLOCSTMT(conn->hdbc, &(result->stmt)); + rc = SQLAllocHandle(SQL_HANDLE_STMT, conn->hdbc, &(result->stmt)); if (rc == SQL_INVALID_HANDLE) { php_error_docref(NULL, E_WARNING, "SQLAllocStmt error 'Invalid Handle'"); zval_ptr_dtor(return_value); @@ -3223,7 +3198,7 @@ PHP_FUNCTION(odbc_procedurecolumns) object_init_ex(return_value, odbc_result_ce); result = Z_ODBC_RESULT_P(return_value); - rc = PHP_ODBC_SQLALLOCSTMT(conn->hdbc, &(result->stmt)); + rc = SQLAllocHandle(SQL_HANDLE_STMT, conn->hdbc, &(result->stmt)); if (rc == SQL_INVALID_HANDLE) { php_error_docref(NULL, E_WARNING, "SQLAllocStmt error 'Invalid Handle'"); zval_ptr_dtor(return_value); @@ -3284,7 +3259,7 @@ PHP_FUNCTION(odbc_procedures) object_init_ex(return_value, odbc_result_ce); result = Z_ODBC_RESULT_P(return_value); - rc = PHP_ODBC_SQLALLOCSTMT(conn->hdbc, &(result->stmt)); + rc = SQLAllocHandle(SQL_HANDLE_STMT, conn->hdbc, &(result->stmt)); if (rc == SQL_INVALID_HANDLE) { php_error_docref(NULL, E_WARNING, "SQLAllocStmt error 'Invalid Handle'"); zval_ptr_dtor(return_value); @@ -3350,7 +3325,7 @@ PHP_FUNCTION(odbc_specialcolumns) object_init_ex(return_value, odbc_result_ce); result = Z_ODBC_RESULT_P(return_value); - rc = PHP_ODBC_SQLALLOCSTMT(conn->hdbc, &(result->stmt)); + rc = SQLAllocHandle(SQL_HANDLE_STMT, conn->hdbc, &(result->stmt)); if (rc == SQL_INVALID_HANDLE) { php_error_docref(NULL, E_WARNING, "SQLAllocStmt error 'Invalid Handle'"); zval_ptr_dtor(return_value); @@ -3416,7 +3391,7 @@ PHP_FUNCTION(odbc_statistics) object_init_ex(return_value, odbc_result_ce); result = Z_ODBC_RESULT_P(return_value); - rc = PHP_ODBC_SQLALLOCSTMT(conn->hdbc, &(result->stmt)); + rc = SQLAllocHandle(SQL_HANDLE_STMT, conn->hdbc, &(result->stmt)); if (rc == SQL_INVALID_HANDLE) { php_error_docref(NULL, E_WARNING, "SQLAllocStmt error 'Invalid Handle'"); zval_ptr_dtor(return_value); @@ -3477,7 +3452,7 @@ PHP_FUNCTION(odbc_tableprivileges) object_init_ex(return_value, odbc_result_ce); result = Z_ODBC_RESULT_P(return_value); - rc = PHP_ODBC_SQLALLOCSTMT(conn->hdbc, &(result->stmt)); + rc = SQLAllocHandle(SQL_HANDLE_STMT, conn->hdbc, &(result->stmt)); if (rc == SQL_INVALID_HANDLE) { php_error_docref(NULL, E_WARNING, "SQLAllocStmt error 'Invalid Handle'"); zval_ptr_dtor(return_value); diff --git a/ext/odbc/php_odbc_includes.h b/ext/odbc/php_odbc_includes.h index e0c6330d744..31da0f25ca8 100644 --- a/ext/odbc/php_odbc_includes.h +++ b/ext/odbc/php_odbc_includes.h @@ -102,7 +102,6 @@ #endif #define ODBC_TYPE "unixODBC" -#undef ODBCVER #include #include #define HAVE_SQL_EXTENDED_FETCH 1 @@ -132,8 +131,6 @@ #elif defined(HAVE_DBMAKER) /* DBMaker */ #define ODBC_TYPE "DBMaker" -#undef ODBCVER -#define ODBCVER 0x0300 #define HAVE_SQL_EXTENDED_FETCH 1 #include @@ -265,21 +262,8 @@ void odbc_bindcols(odbc_result *result); void odbc_sql_error(ODBC_SQL_ERROR_PARAMS); -#if defined(ODBCVER) && (ODBCVER >= 0x0300) #define IS_SQL_LONG(x) (x == SQL_LONGVARBINARY || x == SQL_LONGVARCHAR || x == SQL_WLONGVARCHAR) -#define PHP_ODBC_SQLCOLATTRIBUTE SQLColAttribute -#define PHP_ODBC_SQLALLOCSTMT(hdbc, phstmt) SQLAllocHandle(SQL_HANDLE_STMT, hdbc, phstmt) - -#define PHP_ODBC_SQL_DESC_NAME SQL_DESC_NAME -#else -#define IS_SQL_LONG(x) (x == SQL_LONGVARBINARY || x == SQL_LONGVARCHAR) - -#define PHP_ODBC_SQLCOLATTRIBUTE SQLColAttributes -#define PHP_ODBC_SQLALLOCSTMT SQLAllocStmt - -#define PHP_ODBC_SQL_DESC_NAME SQL_COLUMN_NAME -#endif #define IS_SQL_BINARY(x) (x == SQL_BINARY || x == SQL_VARBINARY || x == SQL_LONGVARBINARY) PHP_ODBC_API ZEND_EXTERN_MODULE_GLOBALS(odbc) diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c index 0f1f1c98698..f597df36e29 100644 --- a/ext/opcache/ZendAccelerator.c +++ b/ext/opcache/ZendAccelerator.c @@ -25,6 +25,7 @@ #include "zend_extensions.h" #include "zend_compile.h" #include "ZendAccelerator.h" +#include "zend_modules.h" #include "zend_persist.h" #include "zend_shared_alloc.h" #include "zend_accelerator_module.h" @@ -102,15 +103,13 @@ typedef int gid_t; #include "zend_simd.h" -ZEND_EXTENSION(); +static zend_extension opcache_extension_entry; #ifndef ZTS zend_accel_globals accel_globals; #else int accel_globals_id; -#if defined(COMPILE_DL_OPCACHE) -ZEND_TSRMLS_CACHE_DEFINE() -#endif +size_t accel_globals_offset; #endif /* Points to the structure shared across all PHP processes */ @@ -1736,19 +1735,11 @@ static void zend_accel_set_auto_globals(int mask) ZCG(auto_globals_mask) |= mask; } -static void replay_warnings(uint32_t num_warnings, zend_error_info **warnings) { - for (uint32_t i = 0; i < num_warnings; i++) { - zend_error_info *warning = warnings[i]; - zend_error_zstr_at(warning->type, warning->filename, warning->lineno, warning->message); - } -} - static zend_persistent_script *opcache_compile_file(zend_file_handle *file_handle, int type, zend_op_array **op_array_p) { zend_persistent_script *new_persistent_script; uint32_t orig_functions_count, orig_class_count; zend_op_array *orig_active_op_array; - zval orig_user_error_handler; zend_op_array *op_array; bool do_bailout = false; accel_time_t timestamp = 0; @@ -1816,13 +1807,6 @@ static zend_persistent_script *opcache_compile_file(zend_file_handle *file_handl orig_active_op_array = CG(active_op_array); orig_functions_count = EG(function_table)->nNumUsed; orig_class_count = EG(class_table)->nNumUsed; - ZVAL_COPY_VALUE(&orig_user_error_handler, &EG(user_error_handler)); - - /* Override them with ours */ - ZVAL_UNDEF(&EG(user_error_handler)); - if (ZCG(accel_directives).record_warnings) { - zend_begin_record_errors(); - } zend_try { orig_compiler_options = CG(compiler_options); @@ -1852,13 +1836,12 @@ static zend_persistent_script *opcache_compile_file(zend_file_handle *file_handl /* Restore originals */ CG(active_op_array) = orig_active_op_array; - EG(user_error_handler) = orig_user_error_handler; - EG(record_errors) = 0; if (!op_array) { /* compilation failed */ - zend_free_recorded_errors(); if (do_bailout) { + EG(record_errors) = false; + zend_free_recorded_errors(); zend_bailout(); } return NULL; @@ -1873,10 +1856,6 @@ static zend_persistent_script *opcache_compile_file(zend_file_handle *file_handl zend_accel_move_user_functions(CG(function_table), CG(function_table)->nNumUsed - orig_functions_count, &new_persistent_script->script); zend_accel_move_user_classes(CG(class_table), CG(class_table)->nNumUsed - orig_class_count, &new_persistent_script->script); zend_accel_build_delayed_early_binding_list(new_persistent_script); - new_persistent_script->num_warnings = EG(num_errors); - new_persistent_script->warnings = EG(errors); - EG(num_errors) = 0; - EG(errors) = NULL; efree(op_array); /* we have valid persistent_script, so it's safe to free op_array */ @@ -1958,7 +1937,7 @@ static zend_op_array *file_cache_compile_file(zend_file_handle *file_handle, int } } } - replay_warnings(persistent_script->num_warnings, persistent_script->warnings); + zend_emit_recorded_errors_ex(persistent_script->num_warnings, persistent_script->warnings); 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)); @@ -1967,14 +1946,28 @@ static zend_op_array *file_cache_compile_file(zend_file_handle *file_handle, int return zend_accel_load_script(persistent_script, 1); } + zend_begin_record_errors(); + persistent_script = opcache_compile_file(file_handle, type, &op_array); if (persistent_script) { + if (ZCG(accel_directives).record_warnings) { + persistent_script->num_warnings = EG(num_errors); + persistent_script->warnings = EG(errors); + } + from_memory = false; persistent_script = cache_script_in_file_cache(persistent_script, &from_memory); + + zend_emit_recorded_errors(); + zend_free_recorded_errors(); + return zend_accel_load_script(persistent_script, from_memory); } + zend_emit_recorded_errors(); + zend_free_recorded_errors(); + return op_array; } @@ -2170,6 +2163,8 @@ zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type) return accelerator_orig_compile_file(file_handle, type); } + zend_begin_record_errors(); + SHM_PROTECT(); HANDLE_UNBLOCK_INTERRUPTIONS(); persistent_script = opcache_compile_file(file_handle, type, &op_array); @@ -2181,6 +2176,11 @@ zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type) */ from_shared_memory = false; if (persistent_script) { + if (ZCG(accel_directives).record_warnings) { + persistent_script->num_warnings = EG(num_errors); + persistent_script->warnings = EG(errors); + } + /* See GH-17246: we disable GC so that user code cannot be executed during the optimizer run. */ bool orig_gc_state = gc_enable(false); persistent_script = cache_script_in_shared_memory(persistent_script, key, &from_shared_memory); @@ -2193,6 +2193,8 @@ zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type) if (!persistent_script) { SHM_PROTECT(); HANDLE_UNBLOCK_INTERRUPTIONS(); + zend_emit_recorded_errors(); + zend_free_recorded_errors(); return op_array; } if (from_shared_memory) { @@ -2206,6 +2208,9 @@ 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(); + + zend_emit_recorded_errors(); + zend_free_recorded_errors(); } else { #ifndef ZEND_WIN32 @@ -2248,7 +2253,7 @@ zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type) SHM_PROTECT(); HANDLE_UNBLOCK_INTERRUPTIONS(); - replay_warnings(persistent_script->num_warnings, persistent_script->warnings); + zend_emit_recorded_errors_ex(persistent_script->num_warnings, persistent_script->warnings); from_shared_memory = true; } @@ -2315,7 +2320,7 @@ static zend_class_entry* zend_accel_inheritance_cache_get(zend_class_entry *ce, entry = zend_accel_inheritance_cache_find(entry, ce, parent, traits_and_interfaces, &needs_autoload); if (entry) { if (!needs_autoload) { - replay_warnings(entry->num_warnings, entry->warnings); + zend_emit_recorded_errors_ex(entry->num_warnings, entry->warnings); if (ZCSG(map_ptr_last) > CG(map_ptr_last)) { zend_map_ptr_extend(ZCSG(map_ptr_last)); } @@ -2469,9 +2474,6 @@ static zend_class_entry* zend_accel_inheritance_cache_add(zend_class_entry *ce, entry->next = proto->inheritance_cache; proto->inheritance_cache = entry; - EG(num_errors) = 0; - EG(errors) = NULL; - ZCSG(map_ptr_last) = CG(map_ptr_last); zend_shared_alloc_destroy_xlat_table(); @@ -2840,39 +2842,12 @@ static void zps_startup_failure(const char *reason, const char *api_reason, int zend_llist_del_element(&zend_extensions, NULL, (int (*)(void *, void *))cb); } -static inline zend_result accel_find_sapi(void) +/* Return whether we are running a CLI (Command LIne) SAPI for which Opcache is + * disabled when `opcache.enable_cli=0` */ +static inline bool accel_sapi_is_cli(void) { - static const char *supported_sapis[] = { - "apache", - "fastcgi", - "cli-server", - "cgi-fcgi", - "fpm-fcgi", - "fpmi-fcgi", - "apache2handler", - "litespeed", - "uwsgi", - "fuzzer", - "frankenphp", - "ngx-php", - NULL - }; - const char **sapi_name; - - if (sapi_module.name) { - for (sapi_name = supported_sapis; *sapi_name; sapi_name++) { - if (strcmp(sapi_module.name, *sapi_name) == 0) { - return SUCCESS; - } - } - if (ZCG(accel_directives).enable_cli && ( - strcmp(sapi_module.name, "cli") == 0 - || strcmp(sapi_module.name, "phpdbg") == 0)) { - return SUCCESS; - } - } - - return FAILURE; + return strcmp(sapi_module.name, "cli") == 0 + || strcmp(sapi_module.name, "phpdbg") == 0; } static zend_result zend_accel_init_shm(void) @@ -2969,9 +2944,6 @@ static zend_result zend_accel_init_shm(void) static void accel_globals_ctor(zend_accel_globals *accel_globals) { -#if defined(COMPILE_DL_OPCACHE) && defined(ZTS) - ZEND_TSRMLS_CACHE_UPDATE(); -#endif memset(accel_globals, 0, sizeof(zend_accel_globals)); accel_globals->key = zend_string_alloc(ZCG_KEY_LEN, true); GC_MAKE_PERSISTENT_LOCAL(accel_globals->key); @@ -3156,10 +3128,15 @@ static void accel_move_code_to_huge_pages(void) # endif /* defined(MAP_HUGETLB) || defined(MADV_HUGEPAGE) */ #endif /* HAVE_HUGE_CODE_PAGES */ +void start_accel_extension(void) +{ + zend_register_extension(&opcache_extension_entry, NULL); +} + static int accel_startup(zend_extension *extension) { #ifdef ZTS - accel_globals_id = ts_allocate_id(&accel_globals_id, sizeof(zend_accel_globals), (ts_allocate_ctor) accel_globals_ctor, (ts_allocate_dtor) accel_globals_dtor); + accel_globals_id = ts_allocate_fast_id(&accel_globals_id, &accel_globals_offset, sizeof(zend_accel_globals), (ts_allocate_ctor) accel_globals_ctor, (ts_allocate_dtor) accel_globals_dtor); #else accel_globals_ctor(&accel_globals); #endif @@ -3174,11 +3151,7 @@ static int accel_startup(zend_extension *extension) # endif #endif - if (start_accel_module() == FAILURE) { - accel_startup_ok = false; - zend_error(E_WARNING, ACCELERATOR_PRODUCT_NAME ": module registration failed!"); - return FAILURE; - } + zend_accel_register_ini_entries(); #ifdef ZEND_WIN32 if (UNEXPECTED(accel_gen_uname_id() == FAILURE)) { @@ -3197,15 +3170,9 @@ static int accel_startup(zend_extension *extension) } #endif - /* no supported SAPI found - disable acceleration and stop initialization */ - if (accel_find_sapi() == FAILURE) { + if (!ZCG(accel_directives).enable_cli && accel_sapi_is_cli()) { accel_startup_ok = false; - if (!ZCG(accel_directives).enable_cli && - strcmp(sapi_module.name, "cli") == 0) { - zps_startup_failure("Opcode Caching is disabled for CLI", NULL, accelerator_remove_cb); - } else { - zps_startup_failure("Opcode Caching is only supported in Apache, FPM, FastCGI, FrankenPHP, LiteSpeed and uWSGI SAPIs", NULL, accelerator_remove_cb); - } + zps_startup_failure("Opcode Caching is disabled for CLI", NULL, accelerator_remove_cb); return SUCCESS; } @@ -3274,6 +3241,12 @@ static zend_result accel_post_startup(void) accel_startup_ok = false; zend_accel_error_noreturn(ACCEL_LOG_FATAL, "Failure to initialize shared memory structures - probably not enough shared memory."); return SUCCESS; + case NO_SHM_BACKEND: + zend_accel_error(ACCEL_LOG_INFO, "Opcode Caching is disabled: No available SHM backend. Set opcache.enable=0 to hide this message."); + zps_startup_failure("No available SHM backend", NULL, accelerator_remove_cb); + /* Do not abort PHP startup */ + return SUCCESS; + case SUCCESSFULLY_REATTACHED: #ifdef HAVE_JIT reattached = true; @@ -3509,6 +3482,8 @@ void accel_shutdown(void) if ((ini_entry = zend_hash_str_find_ptr(EG(ini_directives), "include_path", sizeof("include_path")-1)) != NULL) { ini_entry->on_modify = orig_include_path_on_modify; } + + accel_startup_ok = false; } void zend_accel_schedule_restart(zend_accel_restart_reason reason) @@ -4198,6 +4173,24 @@ static void preload_link(void) preload_remove_declares(op_array); } } ZEND_HASH_FOREACH_END(); + + if (ce->num_hooked_props > 0) { + zend_property_info *info; + + ZEND_HASH_MAP_FOREACH_PTR(&ce->properties_info, info) { + if (info->hooks) { + for (uint32_t i = 0; i < ZEND_PROPERTY_HOOK_COUNT; i++) { + if (info->hooks[i]) { + op_array = &info->hooks[i]->op_array; + ZEND_ASSERT(op_array->type == ZEND_USER_FUNCTION); + if (!(op_array->fn_flags & ZEND_ACC_TRAIT_CLONE)) { + preload_remove_declares(op_array); + } + } + } + } + } ZEND_HASH_FOREACH_END(); + } } ZEND_HASH_FOREACH_END(); } @@ -4858,6 +4851,8 @@ static zend_result accel_finish_startup_preload(bool in_child) bool old_reset_signals = SIGG(reset); #endif + ZCG(preloading) = true; + sapi_module.activate = NULL; sapi_module.deactivate = NULL; sapi_module.register_server_variables = NULL; @@ -4939,6 +4934,8 @@ static zend_result accel_finish_startup_preload(bool in_child) sapi_module.ub_write = orig_ub_write; sapi_module.flush = orig_flush; + ZCG(preloading) = false; + sapi_activate(); return ret; @@ -5005,6 +5002,7 @@ static zend_result accel_finish_startup_preload_subprocess(pid_t *pid) zend_accel_error(ACCEL_LOG_WARNING, "Preloading failed to setuid(%d)", pw->pw_uid); exit(1); } + php_child_init(); } return SUCCESS; @@ -5084,7 +5082,7 @@ static void accel_activate(void) { } } -ZEND_EXT_API zend_extension zend_extension_entry = { +static zend_extension opcache_extension_entry = { ACCELERATOR_PRODUCT_NAME, /* name */ PHP_VERSION, /* version */ "Zend Technologies", /* author */ diff --git a/ext/opcache/ZendAccelerator.h b/ext/opcache/ZendAccelerator.h index 1bac9af9b8b..524a6f5e121 100644 --- a/ext/opcache/ZendAccelerator.h +++ b/ext/opcache/ZendAccelerator.h @@ -220,6 +220,7 @@ typedef struct _zend_accel_globals { #endif void *preloaded_internal_run_time_cache; size_t preloaded_internal_run_time_cache_size; + bool preloading; /* preallocated shared-memory block to save current script */ void *mem; zend_persistent_script *current_persistent_script; @@ -300,11 +301,9 @@ extern zend_accel_shared_globals *accel_shared_globals; #define ZCSG(element) (accel_shared_globals->element) #ifdef ZTS -# define ZCG(v) ZEND_TSRMG(accel_globals_id, zend_accel_globals *, v) +# define ZCG(v) ZEND_TSRMG_FAST(accel_globals_offset, zend_accel_globals *, v) extern int accel_globals_id; -# ifdef COMPILE_DL_OPCACHE -ZEND_TSRMLS_CACHE_EXTERN() -# endif +extern size_t accel_globals_offset; #else # define ZCG(v) (accel_globals.v) extern zend_accel_globals accel_globals; @@ -314,6 +313,7 @@ extern const char *zps_api_failure_reason; BEGIN_EXTERN_C() +void start_accel_extension(void); void accel_shutdown(void); ZEND_RINIT_FUNCTION(zend_accelerator); zend_result accel_post_deactivate(void); diff --git a/ext/opcache/config.m4 b/ext/opcache/config.m4 index 8f6d5ab711b..70138726c56 100644 --- a/ext/opcache/config.m4 +++ b/ext/opcache/config.m4 @@ -1,9 +1,3 @@ -PHP_ARG_ENABLE([opcache], - [whether to enable Zend OPcache support], - [AS_HELP_STRING([--disable-opcache], - [Disable Zend OPcache support])], - [yes]) - PHP_ARG_ENABLE([huge-code-pages], [whether to enable copying PHP CODE pages into HUGE PAGES], [AS_HELP_STRING([--disable-huge-code-pages], @@ -25,89 +19,93 @@ PHP_ARG_WITH([capstone], [no], [no]) -if test "$PHP_OPCACHE" != "no"; then - dnl Always build as shared extension. - ext_shared=yes +AS_VAR_IF([PHP_HUGE_CODE_PAGES], [yes], + [AC_DEFINE([HAVE_HUGE_CODE_PAGES], [1], + [Define to 1 to enable copying PHP CODE pages into HUGE PAGES.])]) - AS_VAR_IF([PHP_HUGE_CODE_PAGES], [yes], - [AC_DEFINE([HAVE_HUGE_CODE_PAGES], [1], - [Define to 1 to enable copying PHP CODE pages into HUGE PAGES.])]) - - AS_VAR_IF([PHP_OPCACHE_JIT], [yes], [ - AS_CASE([$host_cpu], - [[i[34567]86*|x86*|aarch64|amd64]], [], - [ - AC_MSG_WARN([JIT not supported by host architecture]) - PHP_OPCACHE_JIT=no - ]) - - if test "$host_vendor" = "apple" && test "$host_cpu" = "aarch64" && test "$PHP_THREAD_SAFETY" = "yes"; then - AC_MSG_WARN([JIT not supported on Apple Silicon with ZTS]) +AS_VAR_IF([PHP_OPCACHE_JIT], [yes], [ + AS_CASE([$host_cpu], + [[i[34567]86*|x86*|aarch64|amd64]], [], + [ + AC_MSG_WARN([JIT not supported by host architecture]) PHP_OPCACHE_JIT=no - fi + ]) + + if test "$host_vendor" = "apple" && test "$host_cpu" = "aarch64" && test "$PHP_THREAD_SAFETY" = "yes"; then + AC_MSG_WARN([JIT not supported on Apple Silicon with ZTS]) + PHP_OPCACHE_JIT=no + fi +]) + +AS_VAR_IF([PHP_OPCACHE_JIT], [yes], [ + AC_DEFINE([HAVE_JIT], [1], [Define to 1 to enable JIT.]) + ZEND_JIT_SRC=m4_normalize([" + jit/ir/ir_cfg.c + jit/ir/ir_check.c + jit/ir/ir_dump.c + jit/ir/ir_emit.c + jit/ir/ir_gcm.c + jit/ir/ir_gdb.c + jit/ir/ir_patch.c + jit/ir/ir_perf.c + jit/ir/ir_ra.c + jit/ir/ir_save.c + jit/ir/ir_sccp.c + jit/ir/ir_strtab.c + jit/ir/ir.c + jit/zend_jit_vm_helpers.c + jit/zend_jit.c + "]) + + dnl Find out which ABI we are using. + AS_CASE([$host_alias], + [x86_64-*-darwin*], [ + IR_TARGET=IR_TARGET_X64 + DASM_FLAGS="-D X64APPLE=1 -D X64=1" + DASM_ARCH="x86" + TLS_TARGET="darwin" + ], + [*x86_64*|amd64-*-freebsd*], [ + IR_TARGET=IR_TARGET_X64 + DASM_FLAGS="-D X64=1" + DASM_ARCH="x86" + TLS_TARGET="x86_64" + ], + [[i[34567]86*|x86*]], [ + IR_TARGET=IR_TARGET_X86 + DASM_ARCH="x86" + TLS_TARGET="x86" + ], + [aarch64*], [ + IR_TARGET=IR_TARGET_AARCH64 + DASM_ARCH="aarch64" + TLS_TARGET="aarch64" + ]) + + AS_VAR_IF([PHP_CAPSTONE], [yes], + [PKG_CHECK_MODULES([CAPSTONE], [capstone >= 3.0.0], [ + AC_DEFINE([HAVE_CAPSTONE], [1], [Define to 1 if Capstone is available.]) + PHP_EVAL_LIBLINE([$CAPSTONE_LIBS]) + PHP_EVAL_INCLINE([$CAPSTONE_CFLAGS]) + ZEND_JIT_SRC="$ZEND_JIT_SRC jit/ir/ir_disasm.c" + ])]) + + PHP_SUBST([IR_TARGET]) + PHP_SUBST([DASM_FLAGS]) + PHP_SUBST([DASM_ARCH]) + + JIT_CFLAGS="-I@ext_builddir@/jit/ir -D$IR_TARGET -DIR_PHP" + AS_VAR_IF([ZEND_DEBUG], [yes], [JIT_CFLAGS="$JIT_CFLAGS -DIR_DEBUG"]) + + AS_VAR_IF([PHP_THREAD_SAFETY], [yes], [ + ZEND_JIT_SRC="$ZEND_JIT_SRC jit/tls/zend_jit_tls_$TLS_TARGET.c" ]) +]) - AS_VAR_IF([PHP_OPCACHE_JIT], [yes], [ - AC_DEFINE([HAVE_JIT], [1], [Define to 1 to enable JIT.]) - ZEND_JIT_SRC=m4_normalize([" - jit/ir/ir_cfg.c - jit/ir/ir_check.c - jit/ir/ir_dump.c - jit/ir/ir_emit.c - jit/ir/ir_gcm.c - jit/ir/ir_gdb.c - jit/ir/ir_patch.c - jit/ir/ir_perf.c - jit/ir/ir_ra.c - jit/ir/ir_save.c - jit/ir/ir_sccp.c - jit/ir/ir_strtab.c - jit/ir/ir.c - jit/zend_jit_vm_helpers.c - jit/zend_jit.c - "]) +AC_CHECK_FUNCS([mprotect shm_create_largepage]) - dnl Find out which ABI we are using. - AS_CASE([$host_alias], - [x86_64-*-darwin*], [ - IR_TARGET=IR_TARGET_X64 - DASM_FLAGS="-D X64APPLE=1 -D X64=1" - DASM_ARCH="x86" - ], - [*x86_64*|amd64-*-freebsd*], [ - IR_TARGET=IR_TARGET_X64 - DASM_FLAGS="-D X64=1" - DASM_ARCH="x86" - ], - [[i[34567]86*|x86*]], [ - IR_TARGET=IR_TARGET_X86 - DASM_ARCH="x86" - ], - [aarch64*], [ - IR_TARGET=IR_TARGET_AARCH64 - DASM_ARCH="aarch64" - ]) - - AS_VAR_IF([PHP_CAPSTONE], [yes], - [PKG_CHECK_MODULES([CAPSTONE], [capstone >= 3.0.0], [ - AC_DEFINE([HAVE_CAPSTONE], [1], [Define to 1 if Capstone is available.]) - PHP_EVAL_LIBLINE([$CAPSTONE_LIBS], [OPCACHE_SHARED_LIBADD]) - PHP_EVAL_INCLINE([$CAPSTONE_CFLAGS]) - ZEND_JIT_SRC="$ZEND_JIT_SRC jit/ir/ir_disasm.c" - ])]) - - PHP_SUBST([IR_TARGET]) - PHP_SUBST([DASM_FLAGS]) - PHP_SUBST([DASM_ARCH]) - - JIT_CFLAGS="-I@ext_builddir@/jit/ir -D$IR_TARGET -DIR_PHP" - AS_VAR_IF([ZEND_DEBUG], [yes], [JIT_CFLAGS="$JIT_CFLAGS -DIR_DEBUG"]) - ]) - - AC_CHECK_FUNCS([mprotect shm_create_largepage]) - - AC_CACHE_CHECK([for sysvipc shared memory support], [php_cv_shm_ipc], - [AC_RUN_IFELSE([AC_LANG_SOURCE([ +AC_CACHE_CHECK([for sysvipc shared memory support], [php_cv_shm_ipc], + [AC_RUN_IFELSE([AC_LANG_SOURCE([ #include #include #include @@ -309,56 +307,60 @@ int main(void) { } return 0; }]])], - [php_cv_shm_mmap_posix=yes], - [php_cv_shm_mmap_posix=no], - [php_cv_shm_mmap_posix=no]) - ]) + [php_cv_shm_mmap_posix=yes], + [php_cv_shm_mmap_posix=no], + [php_cv_shm_mmap_posix=no]) ]) - LIBS=$LIBS_save +]) +LIBS=$LIBS_save - AS_VAR_IF([php_cv_shm_mmap_posix], [yes], [ - AC_DEFINE([HAVE_SHM_MMAP_POSIX], [1], - [Define to 1 if you have the POSIX mmap() SHM support.]) - AS_CASE([$ac_cv_search_shm_open], ["none required"|no], [], - [PHP_EVAL_LIBLINE([$ac_cv_search_shm_open], [OPCACHE_SHARED_LIBADD])]) - ]) +AS_VAR_IF([php_cv_shm_mmap_posix], [yes], [ + AC_DEFINE([HAVE_SHM_MMAP_POSIX], [1], + [Define to 1 if you have the POSIX mmap() SHM support.]) + AS_CASE([$ac_cv_search_shm_open], ["none required"|no], [], + [PHP_EVAL_LIBLINE([$ac_cv_search_shm_open])]) +]) - PHP_NEW_EXTENSION([opcache], m4_normalize([ - shared_alloc_mmap.c - shared_alloc_posix.c - shared_alloc_shm.c - zend_accelerator_blacklist.c - zend_accelerator_debug.c - zend_accelerator_hash.c - zend_accelerator_module.c - zend_accelerator_util_funcs.c - zend_file_cache.c - zend_persist_calc.c - zend_persist.c - zend_shared_alloc.c - ZendAccelerator.c - $ZEND_JIT_SRC - ]), - [$ext_shared],, - [-DZEND_ENABLE_STATIC_TSRMLS_CACHE=1 $JIT_CFLAGS],, - [yes]) +PHP_NEW_EXTENSION([opcache], m4_normalize([ + shared_alloc_mmap.c + shared_alloc_posix.c + shared_alloc_shm.c + zend_accelerator_api.c + zend_accelerator_blacklist.c + zend_accelerator_debug.c + zend_accelerator_hash.c + zend_accelerator_module.c + zend_accelerator_util_funcs.c + zend_file_cache.c + zend_persist_calc.c + zend_persist.c + zend_shared_alloc.c + ZendAccelerator.c + $ZEND_JIT_SRC + ]), + [no],, + [-DZEND_ENABLE_STATIC_TSRMLS_CACHE=1 $JIT_CFLAGS],, + [yes]) - PHP_ADD_EXTENSION_DEP(opcache, date) - PHP_ADD_EXTENSION_DEP(opcache, pcre) +PHP_ADD_EXTENSION_DEP(opcache, date) +PHP_ADD_EXTENSION_DEP(opcache, pcre) - if test "$php_cv_shm_ipc" != "yes" && test "$php_cv_shm_mmap_posix" != "yes" && test "$php_cv_shm_mmap_anon" != "yes"; then - AC_MSG_FAILURE(m4_text_wrap([ - No supported shared memory caching support was found when configuring - opcache. - ])) - fi - - AS_VAR_IF([PHP_OPCACHE_JIT], [yes], [ - PHP_ADD_BUILD_DIR([ - $ext_builddir/jit - $ext_builddir/jit/ir - ]) - PHP_ADD_MAKEFILE_FRAGMENT([$ext_srcdir/jit/Makefile.frag]) - ]) - PHP_SUBST([OPCACHE_SHARED_LIBADD]) +if test "$php_cv_shm_ipc" != "yes" && test "$php_cv_shm_mmap_posix" != "yes" && test "$php_cv_shm_mmap_anon" != "yes"; then + AC_MSG_WARN(m4_text_wrap([ + No supported shared memory caching support was found when configuring + opcache. Opcache will be disabled. + ])) fi + +AS_VAR_IF([PHP_OPCACHE_JIT], [yes], [ + PHP_ADD_BUILD_DIR([ + $ext_builddir/jit + $ext_builddir/jit/ir + ]) + AS_VAR_IF([PHP_THREAD_SAFETY], [yes], [ + PHP_ADD_BUILD_DIR([$ext_builddir/jit/tls]) + ]) + PHP_ADD_MAKEFILE_FRAGMENT([$ext_srcdir/jit/Makefile.frag]) +]) + +PHP_INSTALL_HEADERS([ext/opcache], [zend_accelerator_api.h]) diff --git a/ext/opcache/config.w32 b/ext/opcache/config.w32 index fa89ca1f18a..9b8f2a7e510 100644 --- a/ext/opcache/config.w32 +++ b/ext/opcache/config.w32 @@ -1,69 +1,73 @@ -ARG_ENABLE("opcache", "whether to enable Zend OPcache support", "yes"); ARG_ENABLE("opcache-jit", "whether to enable JIT (not supported for ARM64)", "yes"); +PHP_OPCACHE="yes"; -if (PHP_OPCACHE != "no") { +ZEND_EXTENSION('opcache', "\ + ZendAccelerator.c \ + zend_accelerator_api.c \ + zend_accelerator_blacklist.c \ + zend_accelerator_debug.c \ + zend_accelerator_hash.c \ + zend_accelerator_module.c \ + zend_accelerator_util_funcs.c \ + zend_persist.c \ + zend_persist_calc.c \ + zend_file_cache.c \ + zend_shared_alloc.c \ + shared_alloc_win32.c", false, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); - ZEND_EXTENSION('opcache', "\ - ZendAccelerator.c \ - zend_accelerator_blacklist.c \ - zend_accelerator_debug.c \ - zend_accelerator_hash.c \ - zend_accelerator_module.c \ - zend_accelerator_util_funcs.c \ - zend_persist.c \ - zend_persist_calc.c \ - zend_file_cache.c \ - zend_shared_alloc.c \ - shared_alloc_win32.c", true, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); +ADD_EXTENSION_DEP('opcache', 'date'); +ADD_EXTENSION_DEP('opcache', 'hash'); +ADD_EXTENSION_DEP('opcache', 'pcre'); - ADD_EXTENSION_DEP('opcache', 'date'); - ADD_EXTENSION_DEP('opcache', 'hash'); - ADD_EXTENSION_DEP('opcache', 'pcre'); +if (PHP_OPCACHE_JIT == "yes") { + if (TARGET_ARCH == 'arm64') { + WARNING("JIT not enabled; not yet supported for ARM64"); + } else if (CHECK_HEADER_ADD_INCLUDE("ir/ir.h", "CFLAGS_OPCACHE", PHP_OPCACHE + ";ext\\opcache\\jit")) { + var dasm_flags = (X64 ? "-D X64=1" : "") + (X64 ? " -D X64WIN=1" : "") + " -D WIN=1"; + var ir_target = (X64 ? "IR_TARGET_X64" : "IR_TARGET_X86"); + var ir_src = "ir_strtab.c ir_cfg.c ir_sccp.c ir_gcm.c ir_ra.c ir_save.c \ + ir_dump.c ir_check.c ir_patch.c"; - if (PHP_OPCACHE_JIT == "yes") { - if (TARGET_ARCH == 'arm64') { - WARNING("JIT not enabled; not yet supported for ARM64"); - } else if (CHECK_HEADER_ADD_INCLUDE("ir/ir.h", "CFLAGS_OPCACHE", PHP_OPCACHE + ";ext\\opcache\\jit")) { - var dasm_flags = (X64 ? "-D X64=1" : "") + (X64 ? " -D X64WIN=1" : "") + " -D WIN=1"; - var ir_target = (X64 ? "IR_TARGET_X64" : "IR_TARGET_X86"); - var ir_src = "ir_strtab.c ir_cfg.c ir_sccp.c ir_gcm.c ir_ra.c ir_save.c \ - ir_dump.c ir_check.c ir_patch.c"; + DEFINE("IR_TARGET", ir_target); + DEFINE("DASM_FLAGS", dasm_flags); + DEFINE("DASM_ARCH", "x86"); + DEFINE("TLS_TARGET", "win"); - DEFINE("IR_TARGET", ir_target); - DEFINE("DASM_FLAGS", dasm_flags); - DEFINE("DASM_ARCH", "x86"); + AC_DEFINE('HAVE_JIT', 1, 'Define to 1 to enable JIT.'); - AC_DEFINE('HAVE_JIT', 1, 'Define to 1 to enable JIT.'); - - ADD_FLAG("CFLAGS_OPCACHE", "/I \"ext\\opcache\\jit\\ir\" /D "+ir_target+" /D IR_PHP"); - if (PHP_DEBUG == "yes") { - ADD_FLAG("CFLAGS_OPCACHE", "/D IR_DEBUG"); - } - - if (CHECK_HEADER_ADD_INCLUDE("capstone\\capstone.h", "CFLAGS_OPCACHE", PHP_OPCACHE+ ";" + PHP_PHP_BUILD + "\\include") && - CHECK_LIB("capstone.lib", "opcache", PHP_OPCACHE)) { - AC_DEFINE('HAVE_CAPSTONE', 1, 'Define to 1 if Capstone is available.'); - ir_src += " ir_disasm.c"; - } - - ADD_MAKEFILE_FRAGMENT(configure_module_dirname + "\\jit\\Makefile.frag.w32"); - - ADD_SOURCES(configure_module_dirname + "\\jit", - "zend_jit.c zend_jit_vm_helpers.c", - "opcache", "ext\\opcache\\jit"); - ADD_SOURCES(configure_module_dirname + "\\jit\\ir", - "ir.c", "opcache", "ext\\opcache\\jit\\ir"); - ADD_SOURCES(configure_module_dirname + "\\jit\\ir", - "ir_emit.c", "opcache", "ext\\opcache\\jit\\ir"); - ADD_SOURCES(configure_module_dirname + "\\jit\\ir", - ir_src, "opcache", "ext\\opcache\\jit\\ir"); - } else { - WARNING("JIT not enabled, headers not found"); + ADD_FLAG("CFLAGS_OPCACHE", "/I \"ext\\opcache\\jit\\ir\" /D "+ir_target+" /D IR_PHP"); + if (PHP_DEBUG == "yes") { + ADD_FLAG("CFLAGS_OPCACHE", "/D IR_DEBUG"); } + + if (CHECK_HEADER_ADD_INCLUDE("capstone\\capstone.h", "CFLAGS_OPCACHE", PHP_OPCACHE+ ";" + PHP_PHP_BUILD + "\\include") && + CHECK_LIB("capstone.lib", "opcache", PHP_OPCACHE)) { + AC_DEFINE('HAVE_CAPSTONE', 1, 'Define to 1 if Capstone is available.'); + ir_src += " ir_disasm.c"; + } + + ADD_MAKEFILE_FRAGMENT(configure_module_dirname + "\\jit\\Makefile.frag.w32"); + + ADD_SOURCES(configure_module_dirname + "\\jit", + "zend_jit.c zend_jit_vm_helpers.c", + "opcache", "ext\\opcache\\jit"); + if (PHP_ZTS == "yes") { + ADD_SOURCES(configure_module_dirname + "\\jit\\tls", + "zend_jit_tls_win.c", + "opcache", "ext\\opcache\\jit\\tls"); + } + ADD_SOURCES(configure_module_dirname + "\\jit\\ir", + "ir.c", "opcache", "ext\\opcache\\jit\\ir"); + ADD_SOURCES(configure_module_dirname + "\\jit\\ir", + "ir_emit.c", "opcache", "ext\\opcache\\jit\\ir"); + ADD_SOURCES(configure_module_dirname + "\\jit\\ir", + ir_src, "opcache", "ext\\opcache\\jit\\ir"); + } else { + WARNING("JIT not enabled, headers not found"); } - - ADD_FLAG('CFLAGS_OPCACHE', "/I " + configure_module_dirname); - } +ADD_FLAG('CFLAGS_OPCACHE', "/I " + configure_module_dirname); + +PHP_INSTALL_HEADERS("ext/opcache", "zend_accelerator_api.h"); diff --git a/ext/opcache/jit/Dockerfile.arm64.example b/ext/opcache/jit/Dockerfile.arm64.example index e7b6a03b2db..6665f4ab81b 100644 --- a/ext/opcache/jit/Dockerfile.arm64.example +++ b/ext/opcache/jit/Dockerfile.arm64.example @@ -12,4 +12,4 @@ ADD . /php-src/ WORKDIR /php-src RUN ./buildconf # Compile a minimal debug build. --enable-debug adds runtime assertions and is slower than regular builds. -RUN ./configure --enable-debug --disable-all --enable-opcache && make clean && make -j$(nproc) +RUN ./configure --enable-debug --disable-all && make clean && make -j$(nproc) diff --git a/ext/opcache/jit/README.md b/ext/opcache/jit/README.md index 6ec58378acc..c87c625e845 100644 --- a/ext/opcache/jit/README.md +++ b/ext/opcache/jit/README.md @@ -76,7 +76,7 @@ export LDFLAGS=-L/usr/lib/i386-linux-gnu export CFLAGS='-m32' export CXXFLAGS='-m32' export PKG_CONFIG=/usr/bin/i686-linux-gnu-pkg-config -./configure --disable-all --enable-opcache --build=i686-pc-linux-gnu +./configure --disable-all --build=i686-pc-linux-gnu make -j$(nproc) ``` diff --git a/ext/opcache/jit/ir/ir.c b/ext/opcache/jit/ir/ir.c index a9f55cc0e46..97d32680e4f 100644 --- a/ext/opcache/jit/ir/ir.c +++ b/ext/opcache/jit/ir/ir.c @@ -172,7 +172,7 @@ void ir_print_const(const ir_ctx *ctx, const ir_insn *insn, FILE *f, bool quoted } else if (insn->val.c == '\0') { fprintf(f, "'\\0'"); } else { - fprintf(f, "%u", insn->val.c); + fprintf(f, "%u", (unsigned char)insn->val.c); } break; case IR_I8: @@ -247,6 +247,7 @@ void ir_print_const(const ir_ctx *ctx, const ir_insn *insn, FILE *f, bool quoted #define ir_op_flag_S1X1 (ir_op_flag_S | 1 | (2 << IR_OP_FLAG_OPERANDS_SHIFT)) #define ir_op_flag_S2 (ir_op_flag_S | 2 | (2 << IR_OP_FLAG_OPERANDS_SHIFT)) #define ir_op_flag_S2X1 (ir_op_flag_S | 2 | (3 << IR_OP_FLAG_OPERANDS_SHIFT)) +#define ir_op_flag_S3 (ir_op_flag_S | 3 | (3 << IR_OP_FLAG_OPERANDS_SHIFT)) #define ir_op_flag_SN (ir_op_flag_S | IR_OP_FLAG_VAR_INPUTS) #define ir_op_flag_E (IR_OP_FLAG_CONTROL|IR_OP_FLAG_BB_END) #define ir_op_flag_E1 (ir_op_flag_E | 1 | (1 << IR_OP_FLAG_OPERANDS_SHIFT)) @@ -803,7 +804,9 @@ ir_ref ir_proto(ir_ctx *ctx, uint8_t flags, ir_type ret_type, uint32_t params_co proto->flags = flags; proto->ret_type = ret_type; proto->params_count = params_count; - memcpy(proto->param_types, param_types, params_count); + if (params_count) { + memcpy(proto->param_types, param_types, params_count); + } return ir_strl(ctx, (const char *)proto, offsetof(ir_proto_t, param_types) + params_count); } @@ -1080,7 +1083,7 @@ ir_ref ir_emit_N(ir_ctx *ctx, uint32_t opt, int32_t count) ir_ref *p, ref = ctx->insns_count; ir_insn *insn; - IR_ASSERT(count >= 0); + IR_ASSERT(count >= 0 && count < 65536); while (UNEXPECTED(ref + count/4 >= ctx->insns_limit)) { ir_grow_top(ctx); } @@ -2973,6 +2976,12 @@ void _ir_CASE_VAL(ir_ctx *ctx, ir_ref switch_ref, ir_ref val) ctx->control = ir_emit2(ctx, IR_CASE_VAL, switch_ref, val); } +void _ir_CASE_RANGE(ir_ctx *ctx, ir_ref switch_ref, ir_ref v1, ir_ref v2) +{ + IR_ASSERT(!ctx->control); + ctx->control = ir_emit3(ctx, IR_CASE_RANGE, switch_ref, v1, v2); +} + void _ir_CASE_DEFAULT(ir_ctx *ctx, ir_ref switch_ref) { IR_ASSERT(!ctx->control); diff --git a/ext/opcache/jit/ir/ir.h b/ext/opcache/jit/ir/ir.h index ec5e57129c9..9575348ff54 100644 --- a/ext/opcache/jit/ir/ir.h +++ b/ext/opcache/jit/ir/ir.h @@ -359,6 +359,7 @@ typedef enum _ir_type { _(IF_TRUE, S1X1, src, prb, ___) /* IF TRUE proj. */ \ _(IF_FALSE, S1X1, src, prb, ___) /* IF FALSE proj. */ \ _(CASE_VAL, S2X1, src, def, prb) /* switch proj. */ \ + _(CASE_RANGE, S3, src, def, def) /* switch proj. */ \ _(CASE_DEFAULT, S1X1, src, prb, ___) /* switch proj. */ \ _(MERGE, SN, src, src, src) /* control merge */ \ _(LOOP_BEGIN, SN, src, src, src) /* loop start */ \ @@ -854,6 +855,9 @@ void ir_gdb_unregister_all(void); bool ir_gdb_present(void); /* IR load API (implementation in ir_load.c) */ +#define IR_RESOLVE_SYM_ADD_THUNK (1<<0) +#define IR_RESOLVE_SYM_SILENT (1<<1) + struct _ir_loader { uint32_t default_func_flags; bool (*init_module) (ir_loader *loader, const char *name, const char *filename, const char *target); @@ -870,7 +874,7 @@ struct _ir_loader { bool (*sym_data_end) (ir_loader *loader, uint32_t flags); bool (*func_init) (ir_loader *loader, ir_ctx *ctx, const char *name); bool (*func_process) (ir_loader *loader, ir_ctx *ctx, const char *name); - void*(*resolve_sym_name) (ir_loader *loader, const char *name, bool add_thunk); + void*(*resolve_sym_name) (ir_loader *loader, const char *name, uint32_t flags); bool (*has_sym) (ir_loader *loader, const char *name); bool (*add_sym) (ir_loader *loader, const char *name, void *addr); }; @@ -884,11 +888,12 @@ int ir_load_llvm_bitcode(ir_loader *loader, const char *filename); int ir_load_llvm_asm(ir_loader *loader, const char *filename); /* IR save API (implementation in ir_save.c) */ -#define IR_SAVE_CFG (1<<0) /* add info about CFG */ -#define IR_SAVE_CFG_MAP (1<<1) /* add info about CFG block assignment */ -#define IR_SAVE_USE_LISTS (1<<2) /* add info about def->use lists */ -#define IR_SAVE_RULES (1<<3) /* add info about selected code-generation rules */ -#define IR_SAVE_REGS (1<<4) /* add info about selected registers */ +#define IR_SAVE_CFG (1<<0) /* add info about CFG */ +#define IR_SAVE_CFG_MAP (1<<1) /* add info about CFG block assignment */ +#define IR_SAVE_USE_LISTS (1<<2) /* add info about def->use lists */ +#define IR_SAVE_RULES (1<<3) /* add info about selected code-generation rules */ +#define IR_SAVE_REGS (1<<4) /* add info about selected registers */ +#define IR_SAVE_SAFE_NAMES (1<<5) /* add '@' prefix to symbol names */ void ir_print_proto(const ir_ctx *ctx, ir_ref proto, FILE *f); void ir_save(const ir_ctx *ctx, uint32_t save_flags, FILE *f); diff --git a/ext/opcache/jit/ir/ir_aarch64.dasc b/ext/opcache/jit/ir/ir_aarch64.dasc index 772eea7a5d7..476529555e9 100644 --- a/ext/opcache/jit/ir/ir_aarch64.dasc +++ b/ext/opcache/jit/ir/ir_aarch64.dasc @@ -996,6 +996,7 @@ binop_fp: case IR_IF_TRUE: case IR_IF_FALSE: case IR_CASE_VAL: + case IR_CASE_RANGE: case IR_CASE_DEFAULT: case IR_MERGE: case IR_LOOP_BEGIN: @@ -4366,11 +4367,15 @@ static void ir_emit_va_arg(ir_ctx *ctx, ir_ref def, ir_insn *insn) ir_backend_data *data = ctx->data; dasm_State **Dst = &data->dasm_state; ir_type type = insn->type; - ir_reg def_reg = ctx->regs[def][0]; + ir_reg def_reg = IR_REG_NUM(ctx->regs[def][0]); ir_reg op2_reg = ctx->regs[def][2]; ir_reg tmp_reg = ctx->regs[def][3]; int32_t offset; + if (ctx->use_lists[def].count == 1) { + /* dead load */ + return; + } IR_ASSERT(def_reg != IR_REG_NONE && tmp_reg != IR_REG_NONE); if (op2_reg != IR_REG_NONE) { if (IR_REG_SPILLED(op2_reg)) { @@ -4394,11 +4399,15 @@ static void ir_emit_va_arg(ir_ctx *ctx, ir_ref def, ir_insn *insn) ir_backend_data *data = ctx->data; dasm_State **Dst = &data->dasm_state; ir_type type = insn->type; - ir_reg def_reg = ctx->regs[def][0]; + ir_reg def_reg = IR_REG_NUM(ctx->regs[def][0]); ir_reg op2_reg = ctx->regs[def][2]; ir_reg tmp_reg = ctx->regs[def][3]; int32_t offset; + if (ctx->use_lists[def].count == 1) { + /* dead load */ + return; + } IR_ASSERT(def_reg != IR_REG_NONE && tmp_reg != IR_REG_NONE); if (op2_reg != IR_REG_NONE) { if (IR_REG_SPILLED(op2_reg)) { @@ -4465,6 +4474,7 @@ static void ir_emit_switch(ir_ctx *ctx, uint32_t b, ir_ref def, ir_insn *insn) int count = 0; ir_val min, max; ir_reg op1_reg, op2_reg, tmp_reg; + bool has_case_range = 0; type = ctx->ir_base[insn->op2].type; if (IR_IS_TYPE_SIGNED(type)) { @@ -4493,6 +4503,22 @@ static void ir_emit_switch(ir_ctx *ctx, uint32_t b, ir_ref def, ir_insn *insn) max.u64 = (int64_t)IR_MAX(max.u64, val->val.u64); } count++; + } else if (use_insn->op == IR_CASE_RANGE) { + has_case_range = 1; + val = &ctx->ir_base[use_insn->op2]; + IR_ASSERT(!IR_IS_SYM_CONST(val->op)); + ir_insn *val2 = &ctx->ir_base[use_insn->op3]; + IR_ASSERT(!IR_IS_SYM_CONST(val2->op)); + if (IR_IS_TYPE_SIGNED(type)) { + IR_ASSERT(IR_IS_TYPE_SIGNED(val->type)); + min.i64 = IR_MIN(min.i64, val->val.i64); + max.i64 = IR_MAX(max.i64, val2->val.i64); + } else { + IR_ASSERT(!IR_IS_TYPE_SIGNED(val->type)); + min.u64 = (int64_t)IR_MIN(min.u64, val->val.u64); + max.u64 = (int64_t)IR_MAX(max.u64, val2->val.u64); + } + count++; } else { IR_ASSERT(use_insn->op == IR_CASE_DEFAULT); default_label = ir_skip_empty_target_blocks(ctx, use_block); @@ -4510,7 +4536,7 @@ static void ir_emit_switch(ir_ctx *ctx, uint32_t b, ir_ref def, ir_insn *insn) } /* Generate a table jmp or a sequence of calls */ - if (count > 2 && (max.i64-min.i64) < count * 8) { + if (!has_case_range && count > 2 && (max.i64-min.i64) < count * 8) { int *labels = ir_mem_malloc(sizeof(int) * (max.i64 - min.i64 + 1)); for (i = 0; i <= (max.i64 - min.i64); i++) { @@ -4615,6 +4641,38 @@ static void ir_emit_switch(ir_ctx *ctx, uint32_t b, ir_ref def, ir_insn *insn) } | beq =>label + } else if (use_insn->op == IR_CASE_RANGE) { + val = &ctx->ir_base[use_insn->op2]; + IR_ASSERT(!IR_IS_SYM_CONST(val->op)); + label = ir_skip_empty_target_blocks(ctx, use_block); + if (aarch64_may_encode_imm12(val->val.i64)) { + | ASM_REG_IMM_OP cmp, type, op2_reg, val->val.i64 + } else { + ir_emit_load_imm_int(ctx, type, tmp_reg, val->val.i64); + | ASM_REG_REG_OP cmp, type, op2_reg, tmp_reg + + } + if (IR_IS_TYPE_SIGNED(type)) { + | blt >1 + } else { + | blo >1 + } + val = &ctx->ir_base[use_insn->op3]; + IR_ASSERT(!IR_IS_SYM_CONST(val->op)); + label = ir_skip_empty_target_blocks(ctx, use_block); + if (aarch64_may_encode_imm12(val->val.i64)) { + | ASM_REG_IMM_OP cmp, type, op2_reg, val->val.i64 + } else { + ir_emit_load_imm_int(ctx, type, tmp_reg, val->val.i64); + | ASM_REG_REG_OP cmp, type, op2_reg, tmp_reg + + } + if (IR_IS_TYPE_SIGNED(type)) { + | ble =>label + } else { + | bls =>label + } + |1: } } if (default_label) { @@ -4935,6 +4993,28 @@ static void ir_emit_tailcall(ir_ctx *ctx, ir_ref def, ir_insn *insn) return; } + /* Move op2 to a tmp register before epilogue if it's in + * used_preserved_regs, because it will be overridden. */ + + ir_reg op2_reg = IR_REG_NONE; + if (!IR_IS_CONST_REF(insn->op2)) { + op2_reg = ctx->regs[def][2]; + IR_ASSERT(op2_reg != IR_REG_NONE); + + if (IR_REG_SPILLED(op2_reg)) { + op2_reg = IR_REG_INT_TMP; + ir_emit_load(ctx, IR_ADDR, op2_reg, insn->op2); + } else if (IR_REGSET_IN((ir_regset)ctx->used_preserved_regs, IR_REG_NUM(op2_reg))) { + ir_reg orig_op2_reg = op2_reg; + op2_reg = IR_REG_INT_TMP; + + ir_type type = ctx->ir_base[insn->op2].type; + | ASM_REG_REG_OP mov, type, op2_reg, IR_REG_NUM(orig_op2_reg) + } else { + op2_reg = IR_REG_NUM(op2_reg); + } + } + ir_emit_epilogue(ctx); if (IR_IS_CONST_REF(insn->op2)) { @@ -4947,13 +5027,8 @@ static void ir_emit_tailcall(ir_ctx *ctx, ir_ref def, ir_insn *insn) | br Rx(IR_REG_INT_TMP) } } else { - ir_reg op2_reg = ctx->regs[def][2]; - IR_ASSERT(op2_reg != IR_REG_NONE); - if (IR_REG_SPILLED(op2_reg)) { - op2_reg = IR_REG_NUM(op2_reg); - ir_emit_load(ctx, IR_ADDR, op2_reg, insn->op2); - } + IR_ASSERT(!IR_REGSET_IN((ir_regset)ctx->used_preserved_regs, op2_reg)); | br Rx(op2_reg) } } @@ -5590,6 +5665,7 @@ static void ir_allocate_unique_spill_slots(ir_ctx *ctx) case IR_IF_TRUE: case IR_IF_FALSE: case IR_CASE_VAL: + case IR_CASE_RANGE: case IR_CASE_DEFAULT: case IR_MERGE: case IR_LOOP_BEGIN: diff --git a/ext/opcache/jit/ir/ir_builder.h b/ext/opcache/jit/ir/ir_builder.h index 4e4ea53683a..ba1924f8d65 100644 --- a/ext/opcache/jit/ir/ir_builder.h +++ b/ext/opcache/jit/ir/ir_builder.h @@ -603,6 +603,7 @@ extern "C" { #define ir_LOOP_END() _ir_LOOP_END(_ir_CTX) #define ir_SWITCH(_val) _ir_SWITCH(_ir_CTX, (_val)) #define ir_CASE_VAL(_switch, _val) _ir_CASE_VAL(_ir_CTX, (_switch), (_val)) +#define ir_CASE_RANGE(_switch, _v1, _v2) _ir_CASE_RANGE(_ir_CTX, (_switch), (_v1), (_v2)) #define ir_CASE_DEFAULT(_switch) _ir_CASE_DEFAULT(_ir_CTX, (_switch)) #define ir_RETURN(_val) _ir_RETURN(_ir_CTX, (_val)) #define ir_IJMP(_addr) _ir_IJMP(_ir_CTX, (_addr)) @@ -682,6 +683,7 @@ ir_ref _ir_TLS(ir_ctx *ctx, ir_ref index, ir_ref offset); void _ir_UNREACHABLE(ir_ctx *ctx); ir_ref _ir_SWITCH(ir_ctx *ctx, ir_ref val); void _ir_CASE_VAL(ir_ctx *ctx, ir_ref switch_ref, ir_ref val); +void _ir_CASE_RANGE(ir_ctx *ctx, ir_ref switch_ref, ir_ref v1, ir_ref v2); void _ir_CASE_DEFAULT(ir_ctx *ctx, ir_ref switch_ref); void _ir_RETURN(ir_ctx *ctx, ir_ref val); void _ir_IJMP(ir_ctx *ctx, ir_ref addr); diff --git a/ext/opcache/jit/ir/ir_cfg.c b/ext/opcache/jit/ir/ir_cfg.c index 01532c8ea3e..13d66a71302 100644 --- a/ext/opcache/jit/ir/ir_cfg.c +++ b/ext/opcache/jit/ir/ir_cfg.c @@ -244,7 +244,6 @@ int ir_build_cfg(ir_ctx *ctx) _blocks[start] = b; _blocks[end] = b; IR_ASSERT(IR_IS_BB_START(insn->op)); - IR_ASSERT(end > start); bb->start = start; bb->end = end; bb->successors = count; @@ -583,7 +582,6 @@ static int ir_remove_unreachable_blocks(ir_ctx *ctx) return 1; } -#if 0 static void compute_postnum(const ir_ctx *ctx, uint32_t *cur, uint32_t b) { uint32_t i, *p; @@ -607,34 +605,42 @@ static void compute_postnum(const ir_ctx *ctx, uint32_t *cur, uint32_t b) /* Computes dominator tree using algorithm from "A Simple, Fast Dominance Algorithm" by * Cooper, Harvey and Kennedy. */ -int ir_build_dominators_tree(ir_ctx *ctx) +static int ir_build_dominators_tree_slow(ir_ctx *ctx) { uint32_t blocks_count, b, postnum; ir_block *blocks, *bb; uint32_t *edges; bool changed; + blocks = ctx->cfg_blocks; + edges = ctx->cfg_edges; + blocks_count = ctx->cfg_blocks_count; + + /* Clear the dominators tree */ + for (b = 0, bb = &blocks[0]; b <= blocks_count; b++, bb++) { + bb->idom = 0; + bb->dom_depth = 0; + bb->dom_child = 0; + bb->dom_next_child = 0; + } + ctx->flags2 &= ~IR_NO_LOOPS; postnum = 1; compute_postnum(ctx, &postnum, 1); - /* Find immediate dominators */ - blocks = ctx->cfg_blocks; - edges = ctx->cfg_edges; - blocks_count = ctx->cfg_blocks_count; + /* Find immediate dominators by iterative fixed-point algorithm */ blocks[1].idom = 1; do { changed = 0; /* Iterating in Reverse Post Order */ for (b = 2, bb = &blocks[2]; b <= blocks_count; b++, bb++) { IR_ASSERT(!(bb->flags & IR_BB_UNREACHABLE)); + IR_ASSERT(bb->predecessors_count > 0); if (bb->predecessors_count == 1) { uint32_t pred_b = edges[bb->predecessors]; - if (blocks[pred_b].idom <= 0) { - //IR_ASSERT("Wrong blocks order: BB is before its single predecessor"); - } else if (bb->idom != pred_b) { + if (blocks[pred_b].idom > 0 && bb->idom != pred_b) { bb->idom = pred_b; changed = 1; } @@ -680,39 +686,53 @@ int ir_build_dominators_tree(ir_ctx *ctx) } } } while (changed); + + /* Build dominators tree */ blocks[1].idom = 0; blocks[1].dom_depth = 0; - - /* Construct dominators tree */ for (b = 2, bb = &blocks[2]; b <= blocks_count; b++, bb++) { - IR_ASSERT(!(bb->flags & IR_BB_UNREACHABLE)); - if (bb->idom > 0) { - ir_block *idom_bb = &blocks[bb->idom]; + uint32_t idom = bb->idom; + ir_block *idom_bb = &blocks[idom]; - bb->dom_depth = idom_bb->dom_depth + 1; - /* Sort by block number to traverse children in pre-order */ - if (idom_bb->dom_child == 0) { - idom_bb->dom_child = b; - } else if (b < idom_bb->dom_child) { - bb->dom_next_child = idom_bb->dom_child; - idom_bb->dom_child = b; + bb->dom_depth = 0; + /* Sort by block number to traverse children in pre-order */ + if (idom_bb->dom_child == 0) { + idom_bb->dom_child = b; + } else if (b < idom_bb->dom_child) { + bb->dom_next_child = idom_bb->dom_child; + idom_bb->dom_child = b; + } else { + int child = idom_bb->dom_child; + ir_block *child_bb = &blocks[child]; + + while (child_bb->dom_next_child > 0 && b > child_bb->dom_next_child) { + child = child_bb->dom_next_child; + child_bb = &blocks[child]; + } + bb->dom_next_child = child_bb->dom_next_child; + child_bb->dom_next_child = b; + } + } + + /* Recalculate dom_depth for all blocks */ + for (b = 2, bb = &blocks[2]; b <= blocks_count; b++, bb++) { + uint32_t idom = bb->idom; + uint32_t dom_depth = 0; + while (idom) { + dom_depth++; + if (blocks[idom].dom_depth > 0) { + dom_depth += blocks[idom].dom_depth; + break; } else { - int child = idom_bb->dom_child; - ir_block *child_bb = &blocks[child]; - - while (child_bb->dom_next_child > 0 && b > child_bb->dom_next_child) { - child = child_bb->dom_next_child; - child_bb = &blocks[child]; - } - bb->dom_next_child = child_bb->dom_next_child; - child_bb->dom_next_child = b; + idom = blocks[idom].idom; } } + bb->dom_depth = dom_depth; } return 1; } -#else + /* A single pass modification of "A Simple, Fast Dominance Algorithm" by * Cooper, Harvey and Kennedy, that relays on IR block ordering. * It may fallback to the general slow fixed-point algorithm. */ @@ -747,7 +767,11 @@ int ir_build_dominators_tree(ir_ctx *ctx) if (UNEXPECTED(idom >= b)) { /* In rare cases, LOOP_BEGIN.op1 may be a back-edge. Skip back-edges. */ ctx->flags2 &= ~IR_NO_LOOPS; - IR_ASSERT(k > 1 && "Wrong blocks order: BB is before its single predecessor"); +// IR_ASSERT(k > 1 && "Wrong blocks order: BB is before its single predecessor"); + if (UNEXPECTED(k <= 1)) { + ir_list_free(&worklist); + return ir_build_dominators_tree_slow(ctx); + } ir_list_push(&worklist, idom); while (1) { k--; @@ -942,7 +966,6 @@ static int ir_build_dominators_tree_iterative(ir_ctx *ctx) return 1; } -#endif static bool ir_dominates(const ir_block *blocks, uint32_t b1, uint32_t b2) { @@ -958,7 +981,7 @@ static bool ir_dominates(const ir_block *blocks, uint32_t b1, uint32_t b2) int ir_find_loops(ir_ctx *ctx) { - uint32_t i, j, n, count; + uint32_t b, j, n, count; uint32_t *entry_times, *exit_times, *sorted_blocks, time = 1; ir_block *blocks = ctx->cfg_blocks; uint32_t *edges = ctx->cfg_edges; @@ -983,13 +1006,13 @@ int ir_find_loops(ir_ctx *ctx) int child; next: - i = ir_worklist_peek(&work); - if (!entry_times[i]) { - entry_times[i] = time++; + b = ir_worklist_peek(&work); + if (!entry_times[b]) { + entry_times[b] = time++; } - /* Visit blocks immediately dominated by i. */ - bb = &blocks[i]; + /* Visit blocks immediately dominated by "b". */ + bb = &blocks[b]; for (child = bb->dom_child; child > 0; child = blocks[child].dom_next_child) { if (ir_worklist_push(&work, child)) { goto next; @@ -999,17 +1022,17 @@ next: /* Visit join edges. */ if (bb->successors_count) { uint32_t *p = edges + bb->successors; - for (j = 0; j < bb->successors_count; j++,p++) { + for (j = 0; j < bb->successors_count; j++, p++) { uint32_t succ = *p; - if (blocks[succ].idom == i) { + if (blocks[succ].idom == b) { continue; } else if (ir_worklist_push(&work, succ)) { goto next; } } } - exit_times[i] = time++; + exit_times[b] = time++; ir_worklist_pop(&work); } @@ -1018,7 +1041,7 @@ next: j = 1; n = 2; while (j != n) { - i = j; + uint32_t i = j; j = n; for (; i < j; i++) { int child; @@ -1030,9 +1053,82 @@ next: count = n; /* Identify loops. See Sreedhar et al, "Identifying Loops Using DJ Graphs". */ + uint32_t prev_dom_depth = blocks[sorted_blocks[n - 1]].dom_depth; + uint32_t prev_irreducible = 0; while (n > 1) { - i = sorted_blocks[--n]; - ir_block *bb = &blocks[i]; + b = sorted_blocks[--n]; + ir_block *bb = &blocks[b]; + + IR_ASSERT(bb->dom_depth <= prev_dom_depth); + if (UNEXPECTED(prev_irreducible) && bb->dom_depth != prev_dom_depth) { + /* process delyed irreducible loops */ + do { + b = sorted_blocks[prev_irreducible]; + bb = &blocks[b]; + if ((bb->flags & IR_BB_IRREDUCIBLE_LOOP) && !bb->loop_depth) { + /* process irreducible loop */ + uint32_t hdr = b; + + bb->loop_depth = 1; + if (ctx->ir_base[bb->start].op == IR_MERGE) { + ctx->ir_base[bb->start].op = IR_LOOP_BEGIN; + } + + /* find the closing edge(s) of the irreucible loop */ + IR_ASSERT(bb->predecessors_count > 1); + uint32_t *p = &edges[bb->predecessors]; + j = bb->predecessors_count; + do { + uint32_t pred = *p; + + if (entry_times[pred] > entry_times[b] && exit_times[pred] < exit_times[b]) { + if (!ir_worklist_len(&work)) { + ir_bitset_clear(work.visited, ir_bitset_len(ir_worklist_capasity(&work))); + } + blocks[pred].loop_header = 0; /* support for merged loops */ + ir_worklist_push(&work, pred); + } + p++; + } while (--j); + if (ir_worklist_len(&work) == 0) continue; + + /* collect members of the irreducible loop */ + while (ir_worklist_len(&work)) { + b = ir_worklist_pop(&work); + if (b != hdr) { + ir_block *bb = &blocks[b]; + bb->loop_header = hdr; + if (bb->predecessors_count) { + uint32_t *p = &edges[bb->predecessors]; + uint32_t n = bb->predecessors_count; + do { + uint32_t pred = *p; + while (blocks[pred].loop_header > 0) { + pred = blocks[pred].loop_header; + } + if (pred != hdr) { + if (entry_times[pred] > entry_times[hdr] && exit_times[pred] < exit_times[hdr]) { + /* "pred" is a descendant of "hdr" */ + ir_worklist_push(&work, pred); + } else { + /* another entry to the irreducible loop */ + bb->flags |= IR_BB_IRREDUCIBLE_LOOP; + if (ctx->ir_base[bb->start].op == IR_MERGE) { + ctx->ir_base[bb->start].op = IR_LOOP_BEGIN; + } + } + } + p++; + } while (--n); + } + } + } + } + } while (--prev_irreducible != n); + prev_irreducible = 0; + b = sorted_blocks[n]; + bb = &blocks[b]; + } if (bb->predecessors_count > 1) { bool irreducible = 0; @@ -1047,7 +1143,7 @@ next: if (bb->idom != pred) { /* In a loop back-edge (back-join edge), the successor dominates the predecessor. */ - if (ir_dominates(blocks, i, pred)) { + if (ir_dominates(blocks, b, pred)) { if (!ir_worklist_len(&work)) { ir_bitset_clear(work.visited, ir_bitset_len(ir_worklist_capasity(&work))); } @@ -1056,8 +1152,9 @@ next: } else { /* Otherwise it's a cross-join edge. See if it's a branch to an ancestor on the DJ spanning tree. */ - if (entry_times[pred] > entry_times[i] && exit_times[pred] < exit_times[i]) { + if (entry_times[pred] > entry_times[b] && exit_times[pred] < exit_times[b]) { irreducible = 1; + break; } } } @@ -1065,46 +1162,56 @@ next: } while (--j); if (UNEXPECTED(irreducible)) { - // TODO: Support for irreducible loops ??? - bb->flags |= IR_BB_IRREDUCIBLE_LOOP; - ctx->flags2 |= IR_IRREDUCIBLE_CFG; - while (ir_worklist_len(&work)) { - ir_worklist_pop(&work); + bb->flags |= IR_BB_LOOP_HEADER | IR_BB_IRREDUCIBLE_LOOP; + ctx->flags2 |= IR_CFG_HAS_LOOPS | IR_IRREDUCIBLE_CFG; + /* Remember the position of the first irreducible loop to process all the irreducible loops + * after the reducible loops with the same dominator tree depth + */ + if (!prev_irreducible) { + prev_irreducible = n; + prev_dom_depth = bb->dom_depth; } + ir_list_clear(&work.l); } else if (ir_worklist_len(&work)) { + /* collect members of the reducible loop */ + uint32_t hdr = b; + bb->flags |= IR_BB_LOOP_HEADER; ctx->flags2 |= IR_CFG_HAS_LOOPS; bb->loop_depth = 1; + if (ctx->ir_base[bb->start].op == IR_MERGE) { + ctx->ir_base[bb->start].op = IR_LOOP_BEGIN; + } while (ir_worklist_len(&work)) { - j = ir_worklist_pop(&work); - while (blocks[j].loop_header > 0) { - j = blocks[j].loop_header; - } - if (j != i) { - ir_block *bb = &blocks[j]; - if (bb->idom == 0 && j != 1) { - /* Ignore blocks that are unreachable or only abnormally reachable. */ - continue; - } - bb->loop_header = i; + b = ir_worklist_pop(&work); + if (b != hdr) { + ir_block *bb = &blocks[b]; + bb->loop_header = hdr; if (bb->predecessors_count) { uint32_t *p = &edges[bb->predecessors]; - j = bb->predecessors_count; + uint32_t n = bb->predecessors_count; do { - ir_worklist_push(&work, *p); + uint32_t pred = *p; + while (blocks[pred].loop_header > 0) { + pred = blocks[pred].loop_header; + } + if (pred != hdr) { + ir_worklist_push(&work, pred); + } p++; - } while (--j); + } while (--n); } } } } } } + IR_ASSERT(!prev_irreducible); if (ctx->flags2 & IR_CFG_HAS_LOOPS) { for (n = 1; n < count; n++) { - i = sorted_blocks[n]; - ir_block *bb = &blocks[i]; + b = sorted_blocks[n]; + ir_block *bb = &blocks[b]; if (bb->loop_header > 0) { ir_block *loop = &blocks[bb->loop_header]; uint32_t loop_depth = loop->loop_depth; @@ -1389,7 +1496,7 @@ restart: goto restart; } } else if (b != predecessor && ctx->cfg_blocks[predecessor].loop_header != b) { - ir_dump_cfg(ctx, stderr); + /* not a loop back-edge */ IR_ASSERT(b == predecessor || ctx->cfg_blocks[predecessor].loop_header == b); } } diff --git a/ext/opcache/jit/ir/ir_check.c b/ext/opcache/jit/ir/ir_check.c index f12b4776fa1..a791baef5db 100644 --- a/ext/opcache/jit/ir/ir_check.c +++ b/ext/opcache/jit/ir/ir_check.c @@ -213,13 +213,18 @@ bool ir_check(const ir_ctx *ctx) ok = 0; } } - break; - case IR_OPND_CONTROL_DEP: if ((ctx->flags2 & IR_LINEAR) && use >= i && !(insn->op == IR_LOOP_BEGIN)) { fprintf(stderr, "ir_base[%d].ops[%d] invalid forward reference (%d)\n", i, j, use); ok = 0; + } + break; + case IR_OPND_CONTROL_DEP: + if ((ctx->flags2 & IR_LINEAR) + && use >= i) { + fprintf(stderr, "ir_base[%d].ops[%d] invalid forward reference (%d)\n", i, j, use); + ok = 0; } else if (insn->op == IR_PHI) { ir_insn *merge_insn = &ctx->ir_base[insn->op1]; if (merge_insn->op != IR_MERGE && merge_insn->op != IR_LOOP_BEGIN) { diff --git a/ext/opcache/jit/ir/ir_emit.c b/ext/opcache/jit/ir/ir_emit.c index c82655daf48..fab9f56228d 100644 --- a/ext/opcache/jit/ir/ir_emit.c +++ b/ext/opcache/jit/ir/ir_emit.c @@ -309,7 +309,7 @@ static void* ir_sym_addr(ir_ctx *ctx, const ir_insn *addr_insn) { const char *name = ir_get_str(ctx, addr_insn->val.name); void *addr = (ctx->loader && ctx->loader->resolve_sym_name) ? - ctx->loader->resolve_sym_name(ctx->loader, name, 0) : + ctx->loader->resolve_sym_name(ctx->loader, name, IR_RESOLVE_SYM_SILENT) : ir_resolve_sym_name(name); return addr; @@ -320,7 +320,7 @@ static void* ir_sym_val(ir_ctx *ctx, const ir_insn *addr_insn) { const char *name = ir_get_str(ctx, addr_insn->val.name); void *addr = (ctx->loader && ctx->loader->resolve_sym_name) ? - ctx->loader->resolve_sym_name(ctx->loader, name, addr_insn->op == IR_FUNC) : + ctx->loader->resolve_sym_name(ctx->loader, name, addr_insn->op == IR_FUNC ? IR_RESOLVE_SYM_ADD_THUNK : 0) : ir_resolve_sym_name(name); IR_ASSERT(addr); diff --git a/ext/opcache/jit/ir/ir_fold.h b/ext/opcache/jit/ir/ir_fold.h index 88539e52ab0..90112214d0c 100644 --- a/ext/opcache/jit/ir/ir_fold.h +++ b/ext/opcache/jit/ir/ir_fold.h @@ -1909,7 +1909,9 @@ IR_FOLD(SUB(_, SUB)) IR_FOLD(SUB(ADD, ADD)) { if (IR_IS_TYPE_INT(IR_OPT_TYPE(opt))) { - if (op1_insn->op1 == op2_insn->op1) { + if (op1 == op2) { + IR_FOLD_CONST_U(0); + } else if (op1_insn->op1 == op2_insn->op1) { /* (a + b) - (a + c) => b - c */ op1 = op1_insn->op2; op2 = op2_insn->op2; diff --git a/ext/opcache/jit/ir/ir_gcm.c b/ext/opcache/jit/ir/ir_gcm.c index 8bd6be5d10a..4d518d20079 100644 --- a/ext/opcache/jit/ir/ir_gcm.c +++ b/ext/opcache/jit/ir/ir_gcm.c @@ -785,6 +785,139 @@ IR_ALWAYS_INLINE ir_ref ir_count_constant(ir_ref *_xlat, ir_ref ref) return 0; } +IR_ALWAYS_INLINE bool ir_is_good_bb_order(ir_ctx *ctx, uint32_t b, ir_block *bb, ir_ref start) +{ + ir_insn *insn = &ctx->ir_base[start]; + uint32_t n = insn->inputs_count; + ir_ref *p = insn->ops + 1; + + if (n == 1) { + return *p < start; + } else { + IR_ASSERT(n > 1); + for (; n > 0; p++, n--) { + ir_ref input = *p; + if (input < start) { + /* ordered */ + } else if ((bb->flags & IR_BB_LOOP_HEADER) + && (ctx->cfg_map[input] == b || ctx->cfg_blocks[ctx->cfg_map[input]].loop_header == b)) { + /* back-edge of reducible loop */ + } else if ((bb->flags & IR_BB_IRREDUCIBLE_LOOP) + && (ctx->cfg_blocks[ctx->cfg_map[input]].loop_header == ctx->cfg_blocks[b].loop_header)) { + /* closing edge of irreducible loop */ + } else { + return 0; + } + } + return 1; + } +} + +static IR_NEVER_INLINE void ir_fix_bb_order(ir_ctx *ctx, ir_ref *_prev, ir_ref *_next) +{ + uint32_t b, succ, count, *q, *xlat; + ir_block *bb; + ir_ref ref, n, prev; + ir_worklist worklist; + ir_block *new_blocks; + +#if 0 + for (b = 1, bb = ctx->cfg_blocks + 1; b <= ctx->cfg_blocks_count; b++, bb++) { + if (!ir_is_good_bb_order(ctx, b, bb, bb->start)) { + goto fix; + } + } + return; + +fix: +#endif + count = ctx->cfg_blocks_count + 1; + new_blocks = ir_mem_malloc(count * sizeof(ir_block)); + xlat = ir_mem_malloc(count * sizeof(uint32_t)); + ir_worklist_init(&worklist, count); + ir_worklist_push(&worklist, 1); + while (ir_worklist_len(&worklist) != 0) { +next: + b = ir_worklist_peek(&worklist); + bb = &ctx->cfg_blocks[b]; + n = bb->successors_count; + if (n == 1) { + succ = ctx->cfg_edges[bb->successors]; + if (ir_worklist_push(&worklist, succ)) { + goto next; + } + } else if (n > 1) { + uint32_t best = 0; + uint32_t best_loop_depth = 0; + + q = ctx->cfg_edges + bb->successors + n; + do { + q--; + succ = *q; + if (ir_bitset_in(worklist.visited, succ)) { + /* already processed */ + } else if ((ctx->cfg_blocks[succ].flags & IR_BB_LOOP_HEADER) + && (succ == b || ctx->cfg_blocks[b].loop_header == succ)) { + /* back-edge of reducible loop */ + } else if ((ctx->cfg_blocks[succ].flags & IR_BB_IRREDUCIBLE_LOOP) + && (ctx->cfg_blocks[succ].loop_header == ctx->cfg_blocks[b].loop_header)) { + /* closing edge of irreducible loop */ + } else if (!best) { + best = succ; + best_loop_depth = ctx->cfg_blocks[best].loop_depth; + } else if (ctx->cfg_blocks[succ].loop_depth < best_loop_depth) { + /* prefer deeper loop */ + best = succ; + best_loop_depth = ctx->cfg_blocks[best].loop_depth; + } + n--; + } while (n > 0); + if (best) { + ir_worklist_push(&worklist, best); + goto next; + } + } + ir_worklist_pop(&worklist); + count--; + new_blocks[count] = *bb; + xlat[b] = count; + } + IR_ASSERT(count == 1); + xlat[0] = 0; + ir_worklist_free(&worklist); + + prev = 0; + for (b = 1, bb = new_blocks + 1; b <= ctx->cfg_blocks_count; b++, bb++) { + bb->idom = xlat[bb->idom]; + bb->loop_header = xlat[bb->loop_header]; + n = bb->successors_count; + if (n > 0) { + for (q = ctx->cfg_edges + bb->successors; n > 0; q++, n--) { + *q = xlat[*q]; + } + } + n = bb->predecessors_count; + if (n > 0) { + for (q = ctx->cfg_edges + bb->predecessors; n > 0; q++, n--) { + *q = xlat[*q]; + } + } + _next[prev] = bb->start; + _prev[bb->start] = prev; + prev = bb->end; + } + _next[0] = 0; + _next[prev] = 0; + + for (ref = 2; ref < ctx->insns_count; ref++) { + ctx->cfg_map[ref] = xlat[ctx->cfg_map[ref]]; + } + ir_mem_free(xlat); + + ir_mem_free(ctx->cfg_blocks); + ctx->cfg_blocks = new_blocks; +} + int ir_schedule(ir_ctx *ctx) { ir_ctx new_ctx; @@ -800,6 +933,7 @@ int ir_schedule(ir_ctx *ctx) ir_block *bb; ir_insn *insn, *new_insn; ir_use_list *lists, *use_list, *new_list; + bool bad_bb_order = 0; /* Create a double-linked list of nodes ordered by BB, respecting BB->start and BB->end */ IR_ASSERT(_blocks[1] == 1); @@ -818,27 +952,61 @@ int ir_schedule(ir_ctx *ctx) } else if (b > prev_b) { bb = &ctx->cfg_blocks[b]; if (i == bb->start) { - IR_ASSERT(bb->end > bb->start); - prev_b = b; - prev_b_end = bb->end; - _prev[bb->end] = 0; - /* add to the end of the list */ - _next[j] = i; - _prev[i] = j; - j = i; - } else { - IR_ASSERT(i != bb->end); + if (bb->end > bb->start) { + prev_b = b; + prev_b_end = bb->end; + /* add to the end of the list */ + _next[j] = i; + _prev[i] = j; + j = i; + } else { + prev_b = 0; + prev_b_end = 0; + k = bb->end; + while (_blocks[_prev[k]] == b) { + k = _prev[k]; + } + /* insert before "k" */ + _prev[i] = _prev[k]; + _next[i] = k; + _next[_prev[k]] = i; + _prev[k] = i; + } + if (!ir_is_good_bb_order(ctx, b, bb, i)) { + bad_bb_order = 1; + } + } else if (i != bb->end) { /* move down late (see the following loop) */ _next[i] = _move_down; _move_down = i; + } else { + prev_b = 0; + prev_b_end = 0; + if (bb->start > bb->end) { + /* add to the end of the list */ + _next[j] = i; + _prev[i] = j; + j = i; + } else { + k = bb->start; + while (_blocks[_next[k]] == b) { + k = _next[k]; + } + /* insert after "k" */ + _next[i] = _next[k]; + _prev[i] = k; + _prev[_next[k]] = i; + _next[k] = i; + } } } else if (b) { bb = &ctx->cfg_blocks[b]; IR_ASSERT(i != bb->start); - if (_prev[bb->end]) { + if (i > bb->end) { /* move up, insert before the end of the already scheduled BB */ k = bb->end; } else { + IR_ASSERT(i > bb->start); /* move up, insert at the end of the block */ k = ctx->cfg_blocks[b + 1].start; } @@ -883,6 +1051,10 @@ int ir_schedule(ir_ctx *ctx) } #endif + if (bad_bb_order) { + ir_fix_bb_order(ctx, _prev, _next); + } + _xlat = ir_mem_calloc((ctx->consts_count + ctx->insns_count), sizeof(ir_ref)); _xlat += ctx->consts_count; _xlat[IR_TRUE] = IR_TRUE; @@ -904,6 +1076,11 @@ int ir_schedule(ir_ctx *ctx) if (insn->op == IR_CASE_VAL) { IR_ASSERT(insn->op2 < IR_TRUE); consts_count += ir_count_constant(_xlat, insn->op2); + } else if (insn->op == IR_CASE_RANGE) { + IR_ASSERT(insn->op2 < IR_TRUE); + consts_count += ir_count_constant(_xlat, insn->op2); + IR_ASSERT(insn->op3 < IR_TRUE); + consts_count += ir_count_constant(_xlat, insn->op3); } n = insn->inputs_count; insns_count += ir_insn_inputs_to_len(n); diff --git a/ext/opcache/jit/ir/ir_private.h b/ext/opcache/jit/ir/ir_private.h index 69a0101d24e..369b4c34e37 100644 --- a/ext/opcache/jit/ir/ir_private.h +++ b/ext/opcache/jit/ir/ir_private.h @@ -9,6 +9,7 @@ #define IR_PRIVATE_H #include #include +#include #ifdef IR_DEBUG # include @@ -62,7 +63,7 @@ #define IR_MAX(a, b) (((a) > (b)) ? (a) : (b)) #define IR_MIN(a, b) (((a) < (b)) ? (a) : (b)) -#define IR_IS_POWER_OF_TWO(x) (!((x) & ((x) - 1))) +#define IR_IS_POWER_OF_TWO(x) ((x) && (!((x) & ((x) - 1)))) #define IR_LOG2(x) ir_ntzl(x) @@ -257,7 +258,7 @@ IR_ALWAYS_INLINE void* ir_arena_alloc(ir_arena **arena_ptr, size_t size) ir_arena *arena = *arena_ptr; char *ptr = (char*)IR_ALIGNED_SIZE((uintptr_t)arena->ptr, 8); - if (EXPECTED(size <= (size_t)(arena->end - ptr))) { + if (EXPECTED((ptrdiff_t)size <= (ptrdiff_t)(arena->end - ptr))) { arena->ptr = ptr + size; } else { size_t arena_size = diff --git a/ext/opcache/jit/ir/ir_save.c b/ext/opcache/jit/ir/ir_save.c index b12cc267af6..ea787f162ec 100644 --- a/ext/opcache/jit/ir/ir_save.c +++ b/ext/opcache/jit/ir/ir_save.c @@ -97,10 +97,14 @@ void ir_save(const ir_ctx *ctx, uint32_t save_flags, FILE *f) for (i = IR_UNUSED + 1, insn = ctx->ir_base - i; i < ctx->consts_count; i++, insn--) { fprintf(f, "\t%s c_%d = ", ir_type_cname[insn->type], i); if (insn->op == IR_FUNC) { - fprintf(f, "func %s", ir_get_str(ctx, insn->val.name)); + fprintf(f, "func %s%s", + (save_flags & IR_SAVE_SAFE_NAMES) ? "@" : "", + ir_get_str(ctx, insn->val.name)); ir_print_proto(ctx, insn->proto, f); } else if (insn->op == IR_SYM) { - fprintf(f, "sym(%s)", ir_get_str(ctx, insn->val.name)); + fprintf(f, "sym(%s%s)", + (save_flags & IR_SAVE_SAFE_NAMES) ? "@" : "", + ir_get_str(ctx, insn->val.name)); } else if (insn->op == IR_FUNC_ADDR) { fprintf(f, "func *"); ir_print_const(ctx, insn, f, true); @@ -140,6 +144,9 @@ void ir_save(const ir_ctx *ctx, uint32_t save_flags, FILE *f) fprintf(f, ", loop=BB%d(%d)", bb->loop_header, bb->loop_depth); } } + if (bb->flags & IR_BB_IRREDUCIBLE_LOOP) { + fprintf(f, ", IRREDUCIBLE"); + } if (bb->predecessors_count) { uint32_t i; diff --git a/ext/opcache/jit/ir/ir_sccp.c b/ext/opcache/jit/ir/ir_sccp.c index 2e006516df8..ae0eebadee5 100644 --- a/ext/opcache/jit/ir/ir_sccp.c +++ b/ext/opcache/jit/ir/ir_sccp.c @@ -458,6 +458,22 @@ static bool ir_sccp_is_equal(ir_ctx *ctx, ir_insn *_values, ir_ref a, ir_ref b) return v1->val.u64 == v2->val.u64; } +static bool ir_sccp_in_range(ir_ctx *ctx, ir_insn *_values, ir_ref a, ir_ref b, ir_ref c) +{ + ir_insn *v1 = IR_IS_CONST_REF(a) ? &ctx->ir_base[a] : &_values[a]; + ir_insn *v2 = IR_IS_CONST_REF(b) ? &ctx->ir_base[b] : &_values[b]; + ir_insn *v3 = IR_IS_CONST_REF(c) ? &ctx->ir_base[c] : &_values[c]; + + IR_ASSERT(!IR_IS_SYM_CONST(v1->op)); + IR_ASSERT(!IR_IS_SYM_CONST(v2->op)); + IR_ASSERT(!IR_IS_SYM_CONST(v3->op)); + if (IR_IS_TYPE_SIGNED(v1->type)) { + return v1->val.i64 >= v2->val.i64 && v1->val.i64 <= v3->val.i64; + } else { + return v1->val.u64 >= v2->val.u64 && v1->val.u64 <= v3->val.u64; + } +} + #ifdef IR_SCCP_TRACE static void ir_sccp_trace_val(ir_ctx *ctx, ir_insn *_values, ir_ref i) { @@ -676,6 +692,11 @@ static IR_NEVER_INLINE void ir_sccp_analyze(ir_ctx *ctx, ir_insn *_values, ir_bi } } else if (use_insn->op == IR_CASE_DEFAULT) { use_case = use; + } else if (use_insn->op == IR_CASE_RANGE) { + if (ir_sccp_in_range(ctx, _values, insn->op2, use_insn->op2, use_insn->op3)) { + use_case = use; + break; + } } } if (use_case) { @@ -1732,7 +1753,20 @@ static ir_ref ir_promote_i2i(ir_ctx *ctx, ir_type type, ir_ref ref, ir_ref use, ir_ref *p, n, input; if (IR_IS_CONST_REF(ref)) { - return ir_const(ctx, insn->val, type); + ir_val val; + + switch (type) { + case IR_I8: val.i64 = insn->val.i8; break; + case IR_U8: val.u64 = insn->val.u8; break; + case IR_I16: val.i64 = insn->val.i16; break; + case IR_U16: val.u64 = insn->val.u16; break; + case IR_I32: val.i64 = insn->val.i32; break; + case IR_U32: val.u64 = insn->val.u32; break; + case IR_CHAR:val.i64 = insn->val.i8; break; + case IR_BOOL:val.u64 = insn->val.u8 != 0; break; + default: IR_ASSERT(0); val.u64 = 0; + } + return ir_const(ctx, val, type); } else { ir_bitqueue_add(worklist, ref); switch (insn->op) { @@ -2391,7 +2425,7 @@ static bool ir_try_remove_empty_diamond(ir_ctx *ctx, ir_ref ref, ir_insn *insn, } start_ref = end->op1; start = &ctx->ir_base[start_ref]; - if (start->op != IR_CASE_VAL && start->op != IR_CASE_DEFAULT) { + if (start->op != IR_CASE_VAL && start->op != IR_CASE_RANGE && start->op != IR_CASE_DEFAULT) { return 0; } if (ctx->use_lists[start_ref].count != 1) { diff --git a/ext/opcache/jit/ir/ir_x86.dasc b/ext/opcache/jit/ir/ir_x86.dasc index 76602c2b4bc..d9967d24dbe 100644 --- a/ext/opcache/jit/ir/ir_x86.dasc +++ b/ext/opcache/jit/ir/ir_x86.dasc @@ -1569,6 +1569,20 @@ op2_const: constraints->tmp_regs[0] = IR_TMP_REG(1, IR_ADDR, IR_LOAD_SUB_REF, IR_DEF_SUB_REF); n = 1; break; + case IR_SSE_SQRT: + case IR_SSE_RINT: + case IR_SSE_FLOOR: + case IR_SSE_CEIL: + case IR_SSE_TRUNC: + case IR_SSE_NEARBYINT: + insn = &ctx->ir_base[ref]; + flags = IR_USE_MUST_BE_IN_REG | IR_OP3_MUST_BE_IN_REG; + if (IR_IS_CONST_REF(insn->op3)) { + const ir_insn *val_insn = &ctx->ir_base[insn->op3]; + constraints->tmp_regs[n] = IR_TMP_REG(3, val_insn->type, IR_LOAD_SUB_REF, IR_DEF_SUB_REF); + n = 1; + } + break; } constraints->tmps_count = n; @@ -2630,6 +2644,7 @@ store_int: case IR_IF_TRUE: case IR_IF_FALSE: case IR_CASE_VAL: + case IR_CASE_RANGE: case IR_CASE_DEFAULT: case IR_MERGE: case IR_LOOP_BEGIN: @@ -6868,7 +6883,24 @@ static void ir_emit_return_fp(ir_ctx *ctx, ir_ref ref, ir_insn *insn) ir_backend_data *data = ctx->data; dasm_State **Dst = &data->dasm_state; - if (op2_reg == IR_REG_NONE || IR_REG_SPILLED(op2_reg)) { + if (IR_IS_CONST_REF(insn->op2)) { + ir_insn *value = &ctx->ir_base[insn->op2]; + + if ((type == IR_FLOAT && value->val.f == 0.0) || (type == IR_DOUBLE && value->val.d == 0.0)) { + | fldz + } else if ((type == IR_FLOAT && value->val.f == 1.0) || (type == IR_DOUBLE && value->val.d == 1.0)) { + | fld1 + } else { + int label = ir_const_label(ctx, insn->op2); + + if (type == IR_DOUBLE) { + | fld qword [=>label] + } else { + IR_ASSERT(type == IR_FLOAT); + | fld dword [=>label] + } + } + } else if (op2_reg == IR_REG_NONE || IR_REG_SPILLED(op2_reg)) { ir_reg fp; int32_t offset = ir_ref_spill_slot_offset(ctx, insn->op2, &fp); @@ -8442,11 +8474,15 @@ static void ir_emit_va_arg(ir_ctx *ctx, ir_ref def, ir_insn *insn) ir_backend_data *data = ctx->data; dasm_State **Dst = &data->dasm_state; ir_type type = insn->type; - ir_reg def_reg = ctx->regs[def][0]; + ir_reg def_reg = IR_REG_NUM(ctx->regs[def][0]); ir_reg op2_reg = ctx->regs[def][2]; ir_reg tmp_reg = ctx->regs[def][3]; int32_t offset; + if (ctx->use_lists[def].count == 1) { + /* dead load */ + return; + } IR_ASSERT(def_reg != IR_REG_NONE && tmp_reg != IR_REG_NONE); if (op2_reg != IR_REG_NONE) { if (IR_REG_SPILLED(op2_reg)) { @@ -8471,11 +8507,15 @@ static void ir_emit_va_arg(ir_ctx *ctx, ir_ref def, ir_insn *insn) ir_backend_data *data = ctx->data; dasm_State **Dst = &data->dasm_state; ir_type type = insn->type; - ir_reg def_reg = ctx->regs[def][0]; + ir_reg def_reg = IR_REG_NUM(ctx->regs[def][0]); ir_reg op2_reg = ctx->regs[def][2]; ir_reg tmp_reg = ctx->regs[def][3]; int32_t offset; + if (ctx->use_lists[def].count == 1) { + /* dead load */ + return; + } IR_ASSERT(def_reg != IR_REG_NONE&& tmp_reg != IR_REG_NONE); if (op2_reg != IR_REG_NONE) { if (IR_REG_SPILLED(op2_reg)) { @@ -8541,6 +8581,7 @@ static void ir_emit_switch(ir_ctx *ctx, uint32_t b, ir_ref def, ir_insn *insn) ir_val min, max; ir_reg op2_reg = ctx->regs[def][2]; ir_reg tmp_reg = ctx->regs[def][3]; + bool has_case_range = 0; type = ctx->ir_base[insn->op2].type; IR_ASSERT(tmp_reg != IR_REG_NONE); @@ -8570,6 +8611,21 @@ static void ir_emit_switch(ir_ctx *ctx, uint32_t b, ir_ref def, ir_insn *insn) max.u64 = (int64_t)IR_MAX(max.u64, val->val.u64); } count++; + } else if (use_insn->op == IR_CASE_RANGE) { + has_case_range = 1; + val = &ctx->ir_base[use_insn->op2]; + IR_ASSERT(!IR_IS_SYM_CONST(val->op)); + ir_insn *val2 = &ctx->ir_base[use_insn->op3]; + IR_ASSERT(!IR_IS_SYM_CONST(val2->op)); + if (IR_IS_TYPE_SIGNED(type)) { + IR_ASSERT(IR_IS_TYPE_SIGNED(val->type)); + min.i64 = IR_MIN(min.i64, val->val.i64); + max.i64 = IR_MAX(max.i64, val2->val.i64); + } else { + IR_ASSERT(!IR_IS_TYPE_SIGNED(val->type)); + min.u64 = (int64_t)IR_MIN(min.u64, val->val.u64); + max.u64 = (int64_t)IR_MAX(max.u64, val2->val.u64); + } } else { IR_ASSERT(use_insn->op == IR_CASE_DEFAULT); default_label = ir_skip_empty_target_blocks(ctx, use_block); @@ -8583,7 +8639,7 @@ static void ir_emit_switch(ir_ctx *ctx, uint32_t b, ir_ref def, ir_insn *insn) } /* Generate a table jmp or a seqence of calls */ - if (count > 2 && (max.i64-min.i64) < count * 8) { + if (!has_case_range && count > 2 && (max.i64-min.i64) < count * 8) { int *labels = ir_mem_malloc(sizeof(int) * (size_t)(max.i64 - min.i64 + 1)); for (i = 0; i <= (max.i64 - min.i64); i++) { @@ -8747,6 +8803,42 @@ static void ir_emit_switch(ir_ctx *ctx, uint32_t b, ir_ref def, ir_insn *insn) |.endif } | je =>label + } else if (use_insn->op == IR_CASE_RANGE) { + val = &ctx->ir_base[use_insn->op2]; + IR_ASSERT(!IR_IS_SYM_CONST(val->op)); + label = ir_skip_empty_target_blocks(ctx, use_block); + if (IR_IS_32BIT(type, val->val)) { + | ASM_REG_IMM_OP cmp, type, op2_reg, val->val.i32 + } else { + IR_ASSERT(sizeof(void*) == 8); +|.if X64 + | mov64 Ra(tmp_reg), val->val.i64 + | ASM_REG_REG_OP cmp, type, op2_reg, tmp_reg +|.endif + } + if (IR_IS_TYPE_SIGNED(type)) { + | jl >1 + } else { + | jb >1 + } + val = &ctx->ir_base[use_insn->op3]; + IR_ASSERT(!IR_IS_SYM_CONST(val->op3)); + label = ir_skip_empty_target_blocks(ctx, use_block); + if (IR_IS_32BIT(type, val->val)) { + | ASM_REG_IMM_OP cmp, type, op2_reg, val->val.i32 + } else { + IR_ASSERT(sizeof(void*) == 8); +|.if X64 + | mov64 Ra(tmp_reg), val->val.i64 + | ASM_REG_REG_OP cmp, type, op2_reg, tmp_reg +|.endif + } + if (IR_IS_TYPE_SIGNED(type)) { + | jle =>label + } else { + | jbe =>label + } + |1: } } if (default_label) { @@ -9221,6 +9313,58 @@ static void ir_emit_tailcall(ir_ctx *ctx, ir_ref def, ir_insn *insn) return; } + /* Move op2 to a tmp register before epilogue if it's in + * used_preserved_regs, because it will be overridden. */ + + ir_reg op2_reg = IR_REG_NONE; + ir_mem mem = IR_MEM_B(IR_REG_NONE); + if (!IR_IS_CONST_REF(insn->op2)) { + op2_reg = ctx->regs[def][2]; + + ir_regset preserved_regs = (ir_regset)ctx->used_preserved_regs | IR_REGSET(IR_REG_STACK_POINTER); + if (ctx->flags & IR_USE_FRAME_POINTER) { + preserved_regs |= IR_REGSET(IR_REG_FRAME_POINTER); + } + + bool is_spill_slot = op2_reg != IR_REG_NONE + && IR_REG_SPILLED(op2_reg) + && ctx->vregs[insn->op2]; + + if (op2_reg != IR_REG_NONE && !is_spill_slot) { + if (IR_REGSET_IN(preserved_regs, IR_REG_NUM(op2_reg))) { + ir_ref orig_op2_reg = op2_reg; + op2_reg = IR_REG_RAX; + + if (IR_REG_SPILLED(orig_op2_reg)) { + ir_emit_load(ctx, IR_ADDR, op2_reg, insn->op2); + } else { + ir_type type = ctx->ir_base[insn->op2].type; + | ASM_REG_REG_OP mov, type, op2_reg, IR_REG_NUM(orig_op2_reg) + } + } else { + op2_reg = IR_REG_NUM(op2_reg); + } + } else { + if (ir_rule(ctx, insn->op2) & IR_FUSED) { + IR_ASSERT(op2_reg == IR_REG_NONE); + mem = ir_fuse_load(ctx, def, insn->op2); + } else { + mem = ir_ref_spill_slot(ctx, insn->op2); + } + ir_reg base = IR_MEM_BASE(mem); + ir_reg index = IR_MEM_INDEX(mem); + if ((base != IR_REG_NONE && IR_REGSET_IN(preserved_regs, base)) || + (index != IR_REG_NONE && IR_REGSET_IN(preserved_regs, index))) { + op2_reg = IR_REG_RAX; + + ir_type type = ctx->ir_base[insn->op2].type; + ir_emit_load_mem_int(ctx, type, op2_reg, mem); + } else { + op2_reg = IR_REG_NONE; + } + } + } + ir_emit_epilogue(ctx); if (IR_IS_CONST_REF(insn->op2)) { @@ -9246,22 +9390,10 @@ static void ir_emit_tailcall(ir_ctx *ctx, ir_ref def, ir_insn *insn) |.endif } } else { - ir_reg op2_reg = ctx->regs[def][2]; - if (op2_reg != IR_REG_NONE) { - if (IR_REG_SPILLED(op2_reg)) { - op2_reg = IR_REG_NUM(op2_reg); - ir_emit_load(ctx, IR_ADDR, op2_reg, insn->op2); - } + IR_ASSERT(!IR_REGSET_IN((ir_regset)ctx->used_preserved_regs, op2_reg)); | jmp Ra(op2_reg) } else { - ir_mem mem; - - if (ir_rule(ctx, insn->op2) & IR_FUSED) { - mem = ir_fuse_load(ctx, def, insn->op2); - } else { - mem = ir_ref_spill_slot(ctx, insn->op2); - } | ASM_TMEM_OP jmp, aword, mem } } @@ -10314,6 +10446,7 @@ static void ir_allocate_unique_spill_slots(ir_ctx *ctx) case IR_IF_TRUE: case IR_IF_FALSE: case IR_CASE_VAL: + case IR_CASE_RANGE: case IR_CASE_DEFAULT: case IR_MERGE: case IR_LOOP_BEGIN: diff --git a/ext/opcache/jit/tls/testing/.gitignore b/ext/opcache/jit/tls/testing/.gitignore new file mode 100644 index 00000000000..3873646140f --- /dev/null +++ b/ext/opcache/jit/tls/testing/.gitignore @@ -0,0 +1,4 @@ +*.so +*.o +main +main.dSYM diff --git a/ext/opcache/jit/tls/testing/def-vars.h b/ext/opcache/jit/tls/testing/def-vars.h new file mode 100644 index 00000000000..66cdc2442b8 --- /dev/null +++ b/ext/opcache/jit/tls/testing/def-vars.h @@ -0,0 +1,1030 @@ +/* Declare a few additional TLS variables to fill any surplus space, + * so _tsrm_ls_cache is allocated in the dynamic section. */ + +#define DEF_VAR(prefix, num) __thread void* prefix##num +#define DEF_VARS(prefix) \ + DEF_VAR(prefix, 0000); \ + DEF_VAR(prefix, 0001); \ + DEF_VAR(prefix, 0002); \ + DEF_VAR(prefix, 0003); \ + DEF_VAR(prefix, 0004); \ + DEF_VAR(prefix, 0005); \ + DEF_VAR(prefix, 0006); \ + DEF_VAR(prefix, 0007); \ + DEF_VAR(prefix, 0008); \ + DEF_VAR(prefix, 0009); \ + DEF_VAR(prefix, 0010); \ + DEF_VAR(prefix, 0011); \ + DEF_VAR(prefix, 0012); \ + DEF_VAR(prefix, 0013); \ + DEF_VAR(prefix, 0014); \ + DEF_VAR(prefix, 0015); \ + DEF_VAR(prefix, 0016); \ + DEF_VAR(prefix, 0017); \ + DEF_VAR(prefix, 0018); \ + DEF_VAR(prefix, 0019); \ + DEF_VAR(prefix, 0020); \ + DEF_VAR(prefix, 0021); \ + DEF_VAR(prefix, 0022); \ + DEF_VAR(prefix, 0023); \ + DEF_VAR(prefix, 0024); \ + DEF_VAR(prefix, 0025); \ + DEF_VAR(prefix, 0026); \ + DEF_VAR(prefix, 0027); \ + DEF_VAR(prefix, 0028); \ + DEF_VAR(prefix, 0029); \ + DEF_VAR(prefix, 0030); \ + DEF_VAR(prefix, 0031); \ + DEF_VAR(prefix, 0032); \ + DEF_VAR(prefix, 0033); \ + DEF_VAR(prefix, 0034); \ + DEF_VAR(prefix, 0035); \ + DEF_VAR(prefix, 0036); \ + DEF_VAR(prefix, 0037); \ + DEF_VAR(prefix, 0038); \ + DEF_VAR(prefix, 0039); \ + DEF_VAR(prefix, 0040); \ + DEF_VAR(prefix, 0041); \ + DEF_VAR(prefix, 0042); \ + DEF_VAR(prefix, 0043); \ + DEF_VAR(prefix, 0044); \ + DEF_VAR(prefix, 0045); \ + DEF_VAR(prefix, 0046); \ + DEF_VAR(prefix, 0047); \ + DEF_VAR(prefix, 0048); \ + DEF_VAR(prefix, 0049); \ + DEF_VAR(prefix, 0050); \ + DEF_VAR(prefix, 0051); \ + DEF_VAR(prefix, 0052); \ + DEF_VAR(prefix, 0053); \ + DEF_VAR(prefix, 0054); \ + DEF_VAR(prefix, 0055); \ + DEF_VAR(prefix, 0056); \ + DEF_VAR(prefix, 0057); \ + DEF_VAR(prefix, 0058); \ + DEF_VAR(prefix, 0059); \ + DEF_VAR(prefix, 0060); \ + DEF_VAR(prefix, 0061); \ + DEF_VAR(prefix, 0062); \ + DEF_VAR(prefix, 0063); \ + DEF_VAR(prefix, 0064); \ + DEF_VAR(prefix, 0065); \ + DEF_VAR(prefix, 0066); \ + DEF_VAR(prefix, 0067); \ + DEF_VAR(prefix, 0068); \ + DEF_VAR(prefix, 0069); \ + DEF_VAR(prefix, 0070); \ + DEF_VAR(prefix, 0071); \ + DEF_VAR(prefix, 0072); \ + DEF_VAR(prefix, 0073); \ + DEF_VAR(prefix, 0074); \ + DEF_VAR(prefix, 0075); \ + DEF_VAR(prefix, 0076); \ + DEF_VAR(prefix, 0077); \ + DEF_VAR(prefix, 0078); \ + DEF_VAR(prefix, 0079); \ + DEF_VAR(prefix, 0080); \ + DEF_VAR(prefix, 0081); \ + DEF_VAR(prefix, 0082); \ + DEF_VAR(prefix, 0083); \ + DEF_VAR(prefix, 0084); \ + DEF_VAR(prefix, 0085); \ + DEF_VAR(prefix, 0086); \ + DEF_VAR(prefix, 0087); \ + DEF_VAR(prefix, 0088); \ + DEF_VAR(prefix, 0089); \ + DEF_VAR(prefix, 0090); \ + DEF_VAR(prefix, 0091); \ + DEF_VAR(prefix, 0092); \ + DEF_VAR(prefix, 0093); \ + DEF_VAR(prefix, 0094); \ + DEF_VAR(prefix, 0095); \ + DEF_VAR(prefix, 0096); \ + DEF_VAR(prefix, 0097); \ + DEF_VAR(prefix, 0098); \ + DEF_VAR(prefix, 0099); \ + DEF_VAR(prefix, 0100); \ + DEF_VAR(prefix, 0101); \ + DEF_VAR(prefix, 0102); \ + DEF_VAR(prefix, 0103); \ + DEF_VAR(prefix, 0104); \ + DEF_VAR(prefix, 0105); \ + DEF_VAR(prefix, 0106); \ + DEF_VAR(prefix, 0107); \ + DEF_VAR(prefix, 0108); \ + DEF_VAR(prefix, 0109); \ + DEF_VAR(prefix, 0110); \ + DEF_VAR(prefix, 0111); \ + DEF_VAR(prefix, 0112); \ + DEF_VAR(prefix, 0113); \ + DEF_VAR(prefix, 0114); \ + DEF_VAR(prefix, 0115); \ + DEF_VAR(prefix, 0116); \ + DEF_VAR(prefix, 0117); \ + DEF_VAR(prefix, 0118); \ + DEF_VAR(prefix, 0119); \ + DEF_VAR(prefix, 0120); \ + DEF_VAR(prefix, 0121); \ + DEF_VAR(prefix, 0122); \ + DEF_VAR(prefix, 0123); \ + DEF_VAR(prefix, 0124); \ + DEF_VAR(prefix, 0125); \ + DEF_VAR(prefix, 0126); \ + DEF_VAR(prefix, 0127); \ + DEF_VAR(prefix, 0128); \ + DEF_VAR(prefix, 0129); \ + DEF_VAR(prefix, 0130); \ + DEF_VAR(prefix, 0131); \ + DEF_VAR(prefix, 0132); \ + DEF_VAR(prefix, 0133); \ + DEF_VAR(prefix, 0134); \ + DEF_VAR(prefix, 0135); \ + DEF_VAR(prefix, 0136); \ + DEF_VAR(prefix, 0137); \ + DEF_VAR(prefix, 0138); \ + DEF_VAR(prefix, 0139); \ + DEF_VAR(prefix, 0140); \ + DEF_VAR(prefix, 0141); \ + DEF_VAR(prefix, 0142); \ + DEF_VAR(prefix, 0143); \ + DEF_VAR(prefix, 0144); \ + DEF_VAR(prefix, 0145); \ + DEF_VAR(prefix, 0146); \ + DEF_VAR(prefix, 0147); \ + DEF_VAR(prefix, 0148); \ + DEF_VAR(prefix, 0149); \ + DEF_VAR(prefix, 0150); \ + DEF_VAR(prefix, 0151); \ + DEF_VAR(prefix, 0152); \ + DEF_VAR(prefix, 0153); \ + DEF_VAR(prefix, 0154); \ + DEF_VAR(prefix, 0155); \ + DEF_VAR(prefix, 0156); \ + DEF_VAR(prefix, 0157); \ + DEF_VAR(prefix, 0158); \ + DEF_VAR(prefix, 0159); \ + DEF_VAR(prefix, 0160); \ + DEF_VAR(prefix, 0161); \ + DEF_VAR(prefix, 0162); \ + DEF_VAR(prefix, 0163); \ + DEF_VAR(prefix, 0164); \ + DEF_VAR(prefix, 0165); \ + DEF_VAR(prefix, 0166); \ + DEF_VAR(prefix, 0167); \ + DEF_VAR(prefix, 0168); \ + DEF_VAR(prefix, 0169); \ + DEF_VAR(prefix, 0170); \ + DEF_VAR(prefix, 0171); \ + DEF_VAR(prefix, 0172); \ + DEF_VAR(prefix, 0173); \ + DEF_VAR(prefix, 0174); \ + DEF_VAR(prefix, 0175); \ + DEF_VAR(prefix, 0176); \ + DEF_VAR(prefix, 0177); \ + DEF_VAR(prefix, 0178); \ + DEF_VAR(prefix, 0179); \ + DEF_VAR(prefix, 0180); \ + DEF_VAR(prefix, 0181); \ + DEF_VAR(prefix, 0182); \ + DEF_VAR(prefix, 0183); \ + DEF_VAR(prefix, 0184); \ + DEF_VAR(prefix, 0185); \ + DEF_VAR(prefix, 0186); \ + DEF_VAR(prefix, 0187); \ + DEF_VAR(prefix, 0188); \ + DEF_VAR(prefix, 0189); \ + DEF_VAR(prefix, 0190); \ + DEF_VAR(prefix, 0191); \ + DEF_VAR(prefix, 0192); \ + DEF_VAR(prefix, 0193); \ + DEF_VAR(prefix, 0194); \ + DEF_VAR(prefix, 0195); \ + DEF_VAR(prefix, 0196); \ + DEF_VAR(prefix, 0197); \ + DEF_VAR(prefix, 0198); \ + DEF_VAR(prefix, 0199); \ + DEF_VAR(prefix, 0200); \ + DEF_VAR(prefix, 0201); \ + DEF_VAR(prefix, 0202); \ + DEF_VAR(prefix, 0203); \ + DEF_VAR(prefix, 0204); \ + DEF_VAR(prefix, 0205); \ + DEF_VAR(prefix, 0206); \ + DEF_VAR(prefix, 0207); \ + DEF_VAR(prefix, 0208); \ + DEF_VAR(prefix, 0209); \ + DEF_VAR(prefix, 0210); \ + DEF_VAR(prefix, 0211); \ + DEF_VAR(prefix, 0212); \ + DEF_VAR(prefix, 0213); \ + DEF_VAR(prefix, 0214); \ + DEF_VAR(prefix, 0215); \ + DEF_VAR(prefix, 0216); \ + DEF_VAR(prefix, 0217); \ + DEF_VAR(prefix, 0218); \ + DEF_VAR(prefix, 0219); \ + DEF_VAR(prefix, 0220); \ + DEF_VAR(prefix, 0221); \ + DEF_VAR(prefix, 0222); \ + DEF_VAR(prefix, 0223); \ + DEF_VAR(prefix, 0224); \ + DEF_VAR(prefix, 0225); \ + DEF_VAR(prefix, 0226); \ + DEF_VAR(prefix, 0227); \ + DEF_VAR(prefix, 0228); \ + DEF_VAR(prefix, 0229); \ + DEF_VAR(prefix, 0230); \ + DEF_VAR(prefix, 0231); \ + DEF_VAR(prefix, 0232); \ + DEF_VAR(prefix, 0233); \ + DEF_VAR(prefix, 0234); \ + DEF_VAR(prefix, 0235); \ + DEF_VAR(prefix, 0236); \ + DEF_VAR(prefix, 0237); \ + DEF_VAR(prefix, 0238); \ + DEF_VAR(prefix, 0239); \ + DEF_VAR(prefix, 0240); \ + DEF_VAR(prefix, 0241); \ + DEF_VAR(prefix, 0242); \ + DEF_VAR(prefix, 0243); \ + DEF_VAR(prefix, 0244); \ + DEF_VAR(prefix, 0245); \ + DEF_VAR(prefix, 0246); \ + DEF_VAR(prefix, 0247); \ + DEF_VAR(prefix, 0248); \ + DEF_VAR(prefix, 0249); \ + DEF_VAR(prefix, 0250); \ + DEF_VAR(prefix, 0251); \ + DEF_VAR(prefix, 0252); \ + DEF_VAR(prefix, 0253); \ + DEF_VAR(prefix, 0254); \ + DEF_VAR(prefix, 0255); \ + DEF_VAR(prefix, 0256); \ + DEF_VAR(prefix, 0257); \ + DEF_VAR(prefix, 0258); \ + DEF_VAR(prefix, 0259); \ + DEF_VAR(prefix, 0260); \ + DEF_VAR(prefix, 0261); \ + DEF_VAR(prefix, 0262); \ + DEF_VAR(prefix, 0263); \ + DEF_VAR(prefix, 0264); \ + DEF_VAR(prefix, 0265); \ + DEF_VAR(prefix, 0266); \ + DEF_VAR(prefix, 0267); \ + DEF_VAR(prefix, 0268); \ + DEF_VAR(prefix, 0269); \ + DEF_VAR(prefix, 0270); \ + DEF_VAR(prefix, 0271); \ + DEF_VAR(prefix, 0272); \ + DEF_VAR(prefix, 0273); \ + DEF_VAR(prefix, 0274); \ + DEF_VAR(prefix, 0275); \ + DEF_VAR(prefix, 0276); \ + DEF_VAR(prefix, 0277); \ + DEF_VAR(prefix, 0278); \ + DEF_VAR(prefix, 0279); \ + DEF_VAR(prefix, 0280); \ + DEF_VAR(prefix, 0281); \ + DEF_VAR(prefix, 0282); \ + DEF_VAR(prefix, 0283); \ + DEF_VAR(prefix, 0284); \ + DEF_VAR(prefix, 0285); \ + DEF_VAR(prefix, 0286); \ + DEF_VAR(prefix, 0287); \ + DEF_VAR(prefix, 0288); \ + DEF_VAR(prefix, 0289); \ + DEF_VAR(prefix, 0290); \ + DEF_VAR(prefix, 0291); \ + DEF_VAR(prefix, 0292); \ + DEF_VAR(prefix, 0293); \ + DEF_VAR(prefix, 0294); \ + DEF_VAR(prefix, 0295); \ + DEF_VAR(prefix, 0296); \ + DEF_VAR(prefix, 0297); \ + DEF_VAR(prefix, 0298); \ + DEF_VAR(prefix, 0299); \ + DEF_VAR(prefix, 0300); \ + DEF_VAR(prefix, 0301); \ + DEF_VAR(prefix, 0302); \ + DEF_VAR(prefix, 0303); \ + DEF_VAR(prefix, 0304); \ + DEF_VAR(prefix, 0305); \ + DEF_VAR(prefix, 0306); \ + DEF_VAR(prefix, 0307); \ + DEF_VAR(prefix, 0308); \ + DEF_VAR(prefix, 0309); \ + DEF_VAR(prefix, 0310); \ + DEF_VAR(prefix, 0311); \ + DEF_VAR(prefix, 0312); \ + DEF_VAR(prefix, 0313); \ + DEF_VAR(prefix, 0314); \ + DEF_VAR(prefix, 0315); \ + DEF_VAR(prefix, 0316); \ + DEF_VAR(prefix, 0317); \ + DEF_VAR(prefix, 0318); \ + DEF_VAR(prefix, 0319); \ + DEF_VAR(prefix, 0320); \ + DEF_VAR(prefix, 0321); \ + DEF_VAR(prefix, 0322); \ + DEF_VAR(prefix, 0323); \ + DEF_VAR(prefix, 0324); \ + DEF_VAR(prefix, 0325); \ + DEF_VAR(prefix, 0326); \ + DEF_VAR(prefix, 0327); \ + DEF_VAR(prefix, 0328); \ + DEF_VAR(prefix, 0329); \ + DEF_VAR(prefix, 0330); \ + DEF_VAR(prefix, 0331); \ + DEF_VAR(prefix, 0332); \ + DEF_VAR(prefix, 0333); \ + DEF_VAR(prefix, 0334); \ + DEF_VAR(prefix, 0335); \ + DEF_VAR(prefix, 0336); \ + DEF_VAR(prefix, 0337); \ + DEF_VAR(prefix, 0338); \ + DEF_VAR(prefix, 0339); \ + DEF_VAR(prefix, 0340); \ + DEF_VAR(prefix, 0341); \ + DEF_VAR(prefix, 0342); \ + DEF_VAR(prefix, 0343); \ + DEF_VAR(prefix, 0344); \ + DEF_VAR(prefix, 0345); \ + DEF_VAR(prefix, 0346); \ + DEF_VAR(prefix, 0347); \ + DEF_VAR(prefix, 0348); \ + DEF_VAR(prefix, 0349); \ + DEF_VAR(prefix, 0350); \ + DEF_VAR(prefix, 0351); \ + DEF_VAR(prefix, 0352); \ + DEF_VAR(prefix, 0353); \ + DEF_VAR(prefix, 0354); \ + DEF_VAR(prefix, 0355); \ + DEF_VAR(prefix, 0356); \ + DEF_VAR(prefix, 0357); \ + DEF_VAR(prefix, 0358); \ + DEF_VAR(prefix, 0359); \ + DEF_VAR(prefix, 0360); \ + DEF_VAR(prefix, 0361); \ + DEF_VAR(prefix, 0362); \ + DEF_VAR(prefix, 0363); \ + DEF_VAR(prefix, 0364); \ + DEF_VAR(prefix, 0365); \ + DEF_VAR(prefix, 0366); \ + DEF_VAR(prefix, 0367); \ + DEF_VAR(prefix, 0368); \ + DEF_VAR(prefix, 0369); \ + DEF_VAR(prefix, 0370); \ + DEF_VAR(prefix, 0371); \ + DEF_VAR(prefix, 0372); \ + DEF_VAR(prefix, 0373); \ + DEF_VAR(prefix, 0374); \ + DEF_VAR(prefix, 0375); \ + DEF_VAR(prefix, 0376); \ + DEF_VAR(prefix, 0377); \ + DEF_VAR(prefix, 0378); \ + DEF_VAR(prefix, 0379); \ + DEF_VAR(prefix, 0380); \ + DEF_VAR(prefix, 0381); \ + DEF_VAR(prefix, 0382); \ + DEF_VAR(prefix, 0383); \ + DEF_VAR(prefix, 0384); \ + DEF_VAR(prefix, 0385); \ + DEF_VAR(prefix, 0386); \ + DEF_VAR(prefix, 0387); \ + DEF_VAR(prefix, 0388); \ + DEF_VAR(prefix, 0389); \ + DEF_VAR(prefix, 0390); \ + DEF_VAR(prefix, 0391); \ + DEF_VAR(prefix, 0392); \ + DEF_VAR(prefix, 0393); \ + DEF_VAR(prefix, 0394); \ + DEF_VAR(prefix, 0395); \ + DEF_VAR(prefix, 0396); \ + DEF_VAR(prefix, 0397); \ + DEF_VAR(prefix, 0398); \ + DEF_VAR(prefix, 0399); \ + DEF_VAR(prefix, 0400); \ + DEF_VAR(prefix, 0401); \ + DEF_VAR(prefix, 0402); \ + DEF_VAR(prefix, 0403); \ + DEF_VAR(prefix, 0404); \ + DEF_VAR(prefix, 0405); \ + DEF_VAR(prefix, 0406); \ + DEF_VAR(prefix, 0407); \ + DEF_VAR(prefix, 0408); \ + DEF_VAR(prefix, 0409); \ + DEF_VAR(prefix, 0410); \ + DEF_VAR(prefix, 0411); \ + DEF_VAR(prefix, 0412); \ + DEF_VAR(prefix, 0413); \ + DEF_VAR(prefix, 0414); \ + DEF_VAR(prefix, 0415); \ + DEF_VAR(prefix, 0416); \ + DEF_VAR(prefix, 0417); \ + DEF_VAR(prefix, 0418); \ + DEF_VAR(prefix, 0419); \ + DEF_VAR(prefix, 0420); \ + DEF_VAR(prefix, 0421); \ + DEF_VAR(prefix, 0422); \ + DEF_VAR(prefix, 0423); \ + DEF_VAR(prefix, 0424); \ + DEF_VAR(prefix, 0425); \ + DEF_VAR(prefix, 0426); \ + DEF_VAR(prefix, 0427); \ + DEF_VAR(prefix, 0428); \ + DEF_VAR(prefix, 0429); \ + DEF_VAR(prefix, 0430); \ + DEF_VAR(prefix, 0431); \ + DEF_VAR(prefix, 0432); \ + DEF_VAR(prefix, 0433); \ + DEF_VAR(prefix, 0434); \ + DEF_VAR(prefix, 0435); \ + DEF_VAR(prefix, 0436); \ + DEF_VAR(prefix, 0437); \ + DEF_VAR(prefix, 0438); \ + DEF_VAR(prefix, 0439); \ + DEF_VAR(prefix, 0440); \ + DEF_VAR(prefix, 0441); \ + DEF_VAR(prefix, 0442); \ + DEF_VAR(prefix, 0443); \ + DEF_VAR(prefix, 0444); \ + DEF_VAR(prefix, 0445); \ + DEF_VAR(prefix, 0446); \ + DEF_VAR(prefix, 0447); \ + DEF_VAR(prefix, 0448); \ + DEF_VAR(prefix, 0449); \ + DEF_VAR(prefix, 0450); \ + DEF_VAR(prefix, 0451); \ + DEF_VAR(prefix, 0452); \ + DEF_VAR(prefix, 0453); \ + DEF_VAR(prefix, 0454); \ + DEF_VAR(prefix, 0455); \ + DEF_VAR(prefix, 0456); \ + DEF_VAR(prefix, 0457); \ + DEF_VAR(prefix, 0458); \ + DEF_VAR(prefix, 0459); \ + DEF_VAR(prefix, 0460); \ + DEF_VAR(prefix, 0461); \ + DEF_VAR(prefix, 0462); \ + DEF_VAR(prefix, 0463); \ + DEF_VAR(prefix, 0464); \ + DEF_VAR(prefix, 0465); \ + DEF_VAR(prefix, 0466); \ + DEF_VAR(prefix, 0467); \ + DEF_VAR(prefix, 0468); \ + DEF_VAR(prefix, 0469); \ + DEF_VAR(prefix, 0470); \ + DEF_VAR(prefix, 0471); \ + DEF_VAR(prefix, 0472); \ + DEF_VAR(prefix, 0473); \ + DEF_VAR(prefix, 0474); \ + DEF_VAR(prefix, 0475); \ + DEF_VAR(prefix, 0476); \ + DEF_VAR(prefix, 0477); \ + DEF_VAR(prefix, 0478); \ + DEF_VAR(prefix, 0479); \ + DEF_VAR(prefix, 0480); \ + DEF_VAR(prefix, 0481); \ + DEF_VAR(prefix, 0482); \ + DEF_VAR(prefix, 0483); \ + DEF_VAR(prefix, 0484); \ + DEF_VAR(prefix, 0485); \ + DEF_VAR(prefix, 0486); \ + DEF_VAR(prefix, 0487); \ + DEF_VAR(prefix, 0488); \ + DEF_VAR(prefix, 0489); \ + DEF_VAR(prefix, 0490); \ + DEF_VAR(prefix, 0491); \ + DEF_VAR(prefix, 0492); \ + DEF_VAR(prefix, 0493); \ + DEF_VAR(prefix, 0494); \ + DEF_VAR(prefix, 0495); \ + DEF_VAR(prefix, 0496); \ + DEF_VAR(prefix, 0497); \ + DEF_VAR(prefix, 0498); \ + DEF_VAR(prefix, 0499); \ + DEF_VAR(prefix, 0500); \ + DEF_VAR(prefix, 0501); \ + DEF_VAR(prefix, 0502); \ + DEF_VAR(prefix, 0503); \ + DEF_VAR(prefix, 0504); \ + DEF_VAR(prefix, 0505); \ + DEF_VAR(prefix, 0506); \ + DEF_VAR(prefix, 0507); \ + DEF_VAR(prefix, 0508); \ + DEF_VAR(prefix, 0509); \ + DEF_VAR(prefix, 0510); \ + DEF_VAR(prefix, 0511); \ + DEF_VAR(prefix, 0512); \ + DEF_VAR(prefix, 0513); \ + DEF_VAR(prefix, 0514); \ + DEF_VAR(prefix, 0515); \ + DEF_VAR(prefix, 0516); \ + DEF_VAR(prefix, 0517); \ + DEF_VAR(prefix, 0518); \ + DEF_VAR(prefix, 0519); \ + DEF_VAR(prefix, 0520); \ + DEF_VAR(prefix, 0521); \ + DEF_VAR(prefix, 0522); \ + DEF_VAR(prefix, 0523); \ + DEF_VAR(prefix, 0524); \ + DEF_VAR(prefix, 0525); \ + DEF_VAR(prefix, 0526); \ + DEF_VAR(prefix, 0527); \ + DEF_VAR(prefix, 0528); \ + DEF_VAR(prefix, 0529); \ + DEF_VAR(prefix, 0530); \ + DEF_VAR(prefix, 0531); \ + DEF_VAR(prefix, 0532); \ + DEF_VAR(prefix, 0533); \ + DEF_VAR(prefix, 0534); \ + DEF_VAR(prefix, 0535); \ + DEF_VAR(prefix, 0536); \ + DEF_VAR(prefix, 0537); \ + DEF_VAR(prefix, 0538); \ + DEF_VAR(prefix, 0539); \ + DEF_VAR(prefix, 0540); \ + DEF_VAR(prefix, 0541); \ + DEF_VAR(prefix, 0542); \ + DEF_VAR(prefix, 0543); \ + DEF_VAR(prefix, 0544); \ + DEF_VAR(prefix, 0545); \ + DEF_VAR(prefix, 0546); \ + DEF_VAR(prefix, 0547); \ + DEF_VAR(prefix, 0548); \ + DEF_VAR(prefix, 0549); \ + DEF_VAR(prefix, 0550); \ + DEF_VAR(prefix, 0551); \ + DEF_VAR(prefix, 0552); \ + DEF_VAR(prefix, 0553); \ + DEF_VAR(prefix, 0554); \ + DEF_VAR(prefix, 0555); \ + DEF_VAR(prefix, 0556); \ + DEF_VAR(prefix, 0557); \ + DEF_VAR(prefix, 0558); \ + DEF_VAR(prefix, 0559); \ + DEF_VAR(prefix, 0560); \ + DEF_VAR(prefix, 0561); \ + DEF_VAR(prefix, 0562); \ + DEF_VAR(prefix, 0563); \ + DEF_VAR(prefix, 0564); \ + DEF_VAR(prefix, 0565); \ + DEF_VAR(prefix, 0566); \ + DEF_VAR(prefix, 0567); \ + DEF_VAR(prefix, 0568); \ + DEF_VAR(prefix, 0569); \ + DEF_VAR(prefix, 0570); \ + DEF_VAR(prefix, 0571); \ + DEF_VAR(prefix, 0572); \ + DEF_VAR(prefix, 0573); \ + DEF_VAR(prefix, 0574); \ + DEF_VAR(prefix, 0575); \ + DEF_VAR(prefix, 0576); \ + DEF_VAR(prefix, 0577); \ + DEF_VAR(prefix, 0578); \ + DEF_VAR(prefix, 0579); \ + DEF_VAR(prefix, 0580); \ + DEF_VAR(prefix, 0581); \ + DEF_VAR(prefix, 0582); \ + DEF_VAR(prefix, 0583); \ + DEF_VAR(prefix, 0584); \ + DEF_VAR(prefix, 0585); \ + DEF_VAR(prefix, 0586); \ + DEF_VAR(prefix, 0587); \ + DEF_VAR(prefix, 0588); \ + DEF_VAR(prefix, 0589); \ + DEF_VAR(prefix, 0590); \ + DEF_VAR(prefix, 0591); \ + DEF_VAR(prefix, 0592); \ + DEF_VAR(prefix, 0593); \ + DEF_VAR(prefix, 0594); \ + DEF_VAR(prefix, 0595); \ + DEF_VAR(prefix, 0596); \ + DEF_VAR(prefix, 0597); \ + DEF_VAR(prefix, 0598); \ + DEF_VAR(prefix, 0599); \ + DEF_VAR(prefix, 0600); \ + DEF_VAR(prefix, 0601); \ + DEF_VAR(prefix, 0602); \ + DEF_VAR(prefix, 0603); \ + DEF_VAR(prefix, 0604); \ + DEF_VAR(prefix, 0605); \ + DEF_VAR(prefix, 0606); \ + DEF_VAR(prefix, 0607); \ + DEF_VAR(prefix, 0608); \ + DEF_VAR(prefix, 0609); \ + DEF_VAR(prefix, 0610); \ + DEF_VAR(prefix, 0611); \ + DEF_VAR(prefix, 0612); \ + DEF_VAR(prefix, 0613); \ + DEF_VAR(prefix, 0614); \ + DEF_VAR(prefix, 0615); \ + DEF_VAR(prefix, 0616); \ + DEF_VAR(prefix, 0617); \ + DEF_VAR(prefix, 0618); \ + DEF_VAR(prefix, 0619); \ + DEF_VAR(prefix, 0620); \ + DEF_VAR(prefix, 0621); \ + DEF_VAR(prefix, 0622); \ + DEF_VAR(prefix, 0623); \ + DEF_VAR(prefix, 0624); \ + DEF_VAR(prefix, 0625); \ + DEF_VAR(prefix, 0626); \ + DEF_VAR(prefix, 0627); \ + DEF_VAR(prefix, 0628); \ + DEF_VAR(prefix, 0629); \ + DEF_VAR(prefix, 0630); \ + DEF_VAR(prefix, 0631); \ + DEF_VAR(prefix, 0632); \ + DEF_VAR(prefix, 0633); \ + DEF_VAR(prefix, 0634); \ + DEF_VAR(prefix, 0635); \ + DEF_VAR(prefix, 0636); \ + DEF_VAR(prefix, 0637); \ + DEF_VAR(prefix, 0638); \ + DEF_VAR(prefix, 0639); \ + DEF_VAR(prefix, 0640); \ + DEF_VAR(prefix, 0641); \ + DEF_VAR(prefix, 0642); \ + DEF_VAR(prefix, 0643); \ + DEF_VAR(prefix, 0644); \ + DEF_VAR(prefix, 0645); \ + DEF_VAR(prefix, 0646); \ + DEF_VAR(prefix, 0647); \ + DEF_VAR(prefix, 0648); \ + DEF_VAR(prefix, 0649); \ + DEF_VAR(prefix, 0650); \ + DEF_VAR(prefix, 0651); \ + DEF_VAR(prefix, 0652); \ + DEF_VAR(prefix, 0653); \ + DEF_VAR(prefix, 0654); \ + DEF_VAR(prefix, 0655); \ + DEF_VAR(prefix, 0656); \ + DEF_VAR(prefix, 0657); \ + DEF_VAR(prefix, 0658); \ + DEF_VAR(prefix, 0659); \ + DEF_VAR(prefix, 0660); \ + DEF_VAR(prefix, 0661); \ + DEF_VAR(prefix, 0662); \ + DEF_VAR(prefix, 0663); \ + DEF_VAR(prefix, 0664); \ + DEF_VAR(prefix, 0665); \ + DEF_VAR(prefix, 0666); \ + DEF_VAR(prefix, 0667); \ + DEF_VAR(prefix, 0668); \ + DEF_VAR(prefix, 0669); \ + DEF_VAR(prefix, 0670); \ + DEF_VAR(prefix, 0671); \ + DEF_VAR(prefix, 0672); \ + DEF_VAR(prefix, 0673); \ + DEF_VAR(prefix, 0674); \ + DEF_VAR(prefix, 0675); \ + DEF_VAR(prefix, 0676); \ + DEF_VAR(prefix, 0677); \ + DEF_VAR(prefix, 0678); \ + DEF_VAR(prefix, 0679); \ + DEF_VAR(prefix, 0680); \ + DEF_VAR(prefix, 0681); \ + DEF_VAR(prefix, 0682); \ + DEF_VAR(prefix, 0683); \ + DEF_VAR(prefix, 0684); \ + DEF_VAR(prefix, 0685); \ + DEF_VAR(prefix, 0686); \ + DEF_VAR(prefix, 0687); \ + DEF_VAR(prefix, 0688); \ + DEF_VAR(prefix, 0689); \ + DEF_VAR(prefix, 0690); \ + DEF_VAR(prefix, 0691); \ + DEF_VAR(prefix, 0692); \ + DEF_VAR(prefix, 0693); \ + DEF_VAR(prefix, 0694); \ + DEF_VAR(prefix, 0695); \ + DEF_VAR(prefix, 0696); \ + DEF_VAR(prefix, 0697); \ + DEF_VAR(prefix, 0698); \ + DEF_VAR(prefix, 0699); \ + DEF_VAR(prefix, 0700); \ + DEF_VAR(prefix, 0701); \ + DEF_VAR(prefix, 0702); \ + DEF_VAR(prefix, 0703); \ + DEF_VAR(prefix, 0704); \ + DEF_VAR(prefix, 0705); \ + DEF_VAR(prefix, 0706); \ + DEF_VAR(prefix, 0707); \ + DEF_VAR(prefix, 0708); \ + DEF_VAR(prefix, 0709); \ + DEF_VAR(prefix, 0710); \ + DEF_VAR(prefix, 0711); \ + DEF_VAR(prefix, 0712); \ + DEF_VAR(prefix, 0713); \ + DEF_VAR(prefix, 0714); \ + DEF_VAR(prefix, 0715); \ + DEF_VAR(prefix, 0716); \ + DEF_VAR(prefix, 0717); \ + DEF_VAR(prefix, 0718); \ + DEF_VAR(prefix, 0719); \ + DEF_VAR(prefix, 0720); \ + DEF_VAR(prefix, 0721); \ + DEF_VAR(prefix, 0722); \ + DEF_VAR(prefix, 0723); \ + DEF_VAR(prefix, 0724); \ + DEF_VAR(prefix, 0725); \ + DEF_VAR(prefix, 0726); \ + DEF_VAR(prefix, 0727); \ + DEF_VAR(prefix, 0728); \ + DEF_VAR(prefix, 0729); \ + DEF_VAR(prefix, 0730); \ + DEF_VAR(prefix, 0731); \ + DEF_VAR(prefix, 0732); \ + DEF_VAR(prefix, 0733); \ + DEF_VAR(prefix, 0734); \ + DEF_VAR(prefix, 0735); \ + DEF_VAR(prefix, 0736); \ + DEF_VAR(prefix, 0737); \ + DEF_VAR(prefix, 0738); \ + DEF_VAR(prefix, 0739); \ + DEF_VAR(prefix, 0740); \ + DEF_VAR(prefix, 0741); \ + DEF_VAR(prefix, 0742); \ + DEF_VAR(prefix, 0743); \ + DEF_VAR(prefix, 0744); \ + DEF_VAR(prefix, 0745); \ + DEF_VAR(prefix, 0746); \ + DEF_VAR(prefix, 0747); \ + DEF_VAR(prefix, 0748); \ + DEF_VAR(prefix, 0749); \ + DEF_VAR(prefix, 0750); \ + DEF_VAR(prefix, 0751); \ + DEF_VAR(prefix, 0752); \ + DEF_VAR(prefix, 0753); \ + DEF_VAR(prefix, 0754); \ + DEF_VAR(prefix, 0755); \ + DEF_VAR(prefix, 0756); \ + DEF_VAR(prefix, 0757); \ + DEF_VAR(prefix, 0758); \ + DEF_VAR(prefix, 0759); \ + DEF_VAR(prefix, 0760); \ + DEF_VAR(prefix, 0761); \ + DEF_VAR(prefix, 0762); \ + DEF_VAR(prefix, 0763); \ + DEF_VAR(prefix, 0764); \ + DEF_VAR(prefix, 0765); \ + DEF_VAR(prefix, 0766); \ + DEF_VAR(prefix, 0767); \ + DEF_VAR(prefix, 0768); \ + DEF_VAR(prefix, 0769); \ + DEF_VAR(prefix, 0770); \ + DEF_VAR(prefix, 0771); \ + DEF_VAR(prefix, 0772); \ + DEF_VAR(prefix, 0773); \ + DEF_VAR(prefix, 0774); \ + DEF_VAR(prefix, 0775); \ + DEF_VAR(prefix, 0776); \ + DEF_VAR(prefix, 0777); \ + DEF_VAR(prefix, 0778); \ + DEF_VAR(prefix, 0779); \ + DEF_VAR(prefix, 0780); \ + DEF_VAR(prefix, 0781); \ + DEF_VAR(prefix, 0782); \ + DEF_VAR(prefix, 0783); \ + DEF_VAR(prefix, 0784); \ + DEF_VAR(prefix, 0785); \ + DEF_VAR(prefix, 0786); \ + DEF_VAR(prefix, 0787); \ + DEF_VAR(prefix, 0788); \ + DEF_VAR(prefix, 0789); \ + DEF_VAR(prefix, 0790); \ + DEF_VAR(prefix, 0791); \ + DEF_VAR(prefix, 0792); \ + DEF_VAR(prefix, 0793); \ + DEF_VAR(prefix, 0794); \ + DEF_VAR(prefix, 0795); \ + DEF_VAR(prefix, 0796); \ + DEF_VAR(prefix, 0797); \ + DEF_VAR(prefix, 0798); \ + DEF_VAR(prefix, 0799); \ + DEF_VAR(prefix, 0800); \ + DEF_VAR(prefix, 0801); \ + DEF_VAR(prefix, 0802); \ + DEF_VAR(prefix, 0803); \ + DEF_VAR(prefix, 0804); \ + DEF_VAR(prefix, 0805); \ + DEF_VAR(prefix, 0806); \ + DEF_VAR(prefix, 0807); \ + DEF_VAR(prefix, 0808); \ + DEF_VAR(prefix, 0809); \ + DEF_VAR(prefix, 0810); \ + DEF_VAR(prefix, 0811); \ + DEF_VAR(prefix, 0812); \ + DEF_VAR(prefix, 0813); \ + DEF_VAR(prefix, 0814); \ + DEF_VAR(prefix, 0815); \ + DEF_VAR(prefix, 0816); \ + DEF_VAR(prefix, 0817); \ + DEF_VAR(prefix, 0818); \ + DEF_VAR(prefix, 0819); \ + DEF_VAR(prefix, 0820); \ + DEF_VAR(prefix, 0821); \ + DEF_VAR(prefix, 0822); \ + DEF_VAR(prefix, 0823); \ + DEF_VAR(prefix, 0824); \ + DEF_VAR(prefix, 0825); \ + DEF_VAR(prefix, 0826); \ + DEF_VAR(prefix, 0827); \ + DEF_VAR(prefix, 0828); \ + DEF_VAR(prefix, 0829); \ + DEF_VAR(prefix, 0830); \ + DEF_VAR(prefix, 0831); \ + DEF_VAR(prefix, 0832); \ + DEF_VAR(prefix, 0833); \ + DEF_VAR(prefix, 0834); \ + DEF_VAR(prefix, 0835); \ + DEF_VAR(prefix, 0836); \ + DEF_VAR(prefix, 0837); \ + DEF_VAR(prefix, 0838); \ + DEF_VAR(prefix, 0839); \ + DEF_VAR(prefix, 0840); \ + DEF_VAR(prefix, 0841); \ + DEF_VAR(prefix, 0842); \ + DEF_VAR(prefix, 0843); \ + DEF_VAR(prefix, 0844); \ + DEF_VAR(prefix, 0845); \ + DEF_VAR(prefix, 0846); \ + DEF_VAR(prefix, 0847); \ + DEF_VAR(prefix, 0848); \ + DEF_VAR(prefix, 0849); \ + DEF_VAR(prefix, 0850); \ + DEF_VAR(prefix, 0851); \ + DEF_VAR(prefix, 0852); \ + DEF_VAR(prefix, 0853); \ + DEF_VAR(prefix, 0854); \ + DEF_VAR(prefix, 0855); \ + DEF_VAR(prefix, 0856); \ + DEF_VAR(prefix, 0857); \ + DEF_VAR(prefix, 0858); \ + DEF_VAR(prefix, 0859); \ + DEF_VAR(prefix, 0860); \ + DEF_VAR(prefix, 0861); \ + DEF_VAR(prefix, 0862); \ + DEF_VAR(prefix, 0863); \ + DEF_VAR(prefix, 0864); \ + DEF_VAR(prefix, 0865); \ + DEF_VAR(prefix, 0866); \ + DEF_VAR(prefix, 0867); \ + DEF_VAR(prefix, 0868); \ + DEF_VAR(prefix, 0869); \ + DEF_VAR(prefix, 0870); \ + DEF_VAR(prefix, 0871); \ + DEF_VAR(prefix, 0872); \ + DEF_VAR(prefix, 0873); \ + DEF_VAR(prefix, 0874); \ + DEF_VAR(prefix, 0875); \ + DEF_VAR(prefix, 0876); \ + DEF_VAR(prefix, 0877); \ + DEF_VAR(prefix, 0878); \ + DEF_VAR(prefix, 0879); \ + DEF_VAR(prefix, 0880); \ + DEF_VAR(prefix, 0881); \ + DEF_VAR(prefix, 0882); \ + DEF_VAR(prefix, 0883); \ + DEF_VAR(prefix, 0884); \ + DEF_VAR(prefix, 0885); \ + DEF_VAR(prefix, 0886); \ + DEF_VAR(prefix, 0887); \ + DEF_VAR(prefix, 0888); \ + DEF_VAR(prefix, 0889); \ + DEF_VAR(prefix, 0890); \ + DEF_VAR(prefix, 0891); \ + DEF_VAR(prefix, 0892); \ + DEF_VAR(prefix, 0893); \ + DEF_VAR(prefix, 0894); \ + DEF_VAR(prefix, 0895); \ + DEF_VAR(prefix, 0896); \ + DEF_VAR(prefix, 0897); \ + DEF_VAR(prefix, 0898); \ + DEF_VAR(prefix, 0899); \ + DEF_VAR(prefix, 0900); \ + DEF_VAR(prefix, 0901); \ + DEF_VAR(prefix, 0902); \ + DEF_VAR(prefix, 0903); \ + DEF_VAR(prefix, 0904); \ + DEF_VAR(prefix, 0905); \ + DEF_VAR(prefix, 0906); \ + DEF_VAR(prefix, 0907); \ + DEF_VAR(prefix, 0908); \ + DEF_VAR(prefix, 0909); \ + DEF_VAR(prefix, 0910); \ + DEF_VAR(prefix, 0911); \ + DEF_VAR(prefix, 0912); \ + DEF_VAR(prefix, 0913); \ + DEF_VAR(prefix, 0914); \ + DEF_VAR(prefix, 0915); \ + DEF_VAR(prefix, 0916); \ + DEF_VAR(prefix, 0917); \ + DEF_VAR(prefix, 0918); \ + DEF_VAR(prefix, 0919); \ + DEF_VAR(prefix, 0920); \ + DEF_VAR(prefix, 0921); \ + DEF_VAR(prefix, 0922); \ + DEF_VAR(prefix, 0923); \ + DEF_VAR(prefix, 0924); \ + DEF_VAR(prefix, 0925); \ + DEF_VAR(prefix, 0926); \ + DEF_VAR(prefix, 0927); \ + DEF_VAR(prefix, 0928); \ + DEF_VAR(prefix, 0929); \ + DEF_VAR(prefix, 0930); \ + DEF_VAR(prefix, 0931); \ + DEF_VAR(prefix, 0932); \ + DEF_VAR(prefix, 0933); \ + DEF_VAR(prefix, 0934); \ + DEF_VAR(prefix, 0935); \ + DEF_VAR(prefix, 0936); \ + DEF_VAR(prefix, 0937); \ + DEF_VAR(prefix, 0938); \ + DEF_VAR(prefix, 0939); \ + DEF_VAR(prefix, 0940); \ + DEF_VAR(prefix, 0941); \ + DEF_VAR(prefix, 0942); \ + DEF_VAR(prefix, 0943); \ + DEF_VAR(prefix, 0944); \ + DEF_VAR(prefix, 0945); \ + DEF_VAR(prefix, 0946); \ + DEF_VAR(prefix, 0947); \ + DEF_VAR(prefix, 0948); \ + DEF_VAR(prefix, 0949); \ + DEF_VAR(prefix, 0950); \ + DEF_VAR(prefix, 0951); \ + DEF_VAR(prefix, 0952); \ + DEF_VAR(prefix, 0953); \ + DEF_VAR(prefix, 0954); \ + DEF_VAR(prefix, 0955); \ + DEF_VAR(prefix, 0956); \ + DEF_VAR(prefix, 0957); \ + DEF_VAR(prefix, 0958); \ + DEF_VAR(prefix, 0959); \ + DEF_VAR(prefix, 0960); \ + DEF_VAR(prefix, 0961); \ + DEF_VAR(prefix, 0962); \ + DEF_VAR(prefix, 0963); \ + DEF_VAR(prefix, 0964); \ + DEF_VAR(prefix, 0965); \ + DEF_VAR(prefix, 0966); \ + DEF_VAR(prefix, 0967); \ + DEF_VAR(prefix, 0968); \ + DEF_VAR(prefix, 0969); \ + DEF_VAR(prefix, 0970); \ + DEF_VAR(prefix, 0971); \ + DEF_VAR(prefix, 0972); \ + DEF_VAR(prefix, 0973); \ + DEF_VAR(prefix, 0974); \ + DEF_VAR(prefix, 0975); \ + DEF_VAR(prefix, 0976); \ + DEF_VAR(prefix, 0977); \ + DEF_VAR(prefix, 0978); \ + DEF_VAR(prefix, 0979); \ + DEF_VAR(prefix, 0980); \ + DEF_VAR(prefix, 0981); \ + DEF_VAR(prefix, 0982); \ + DEF_VAR(prefix, 0983); \ + DEF_VAR(prefix, 0984); \ + DEF_VAR(prefix, 0985); \ + DEF_VAR(prefix, 0986); \ + DEF_VAR(prefix, 0987); \ + DEF_VAR(prefix, 0988); \ + DEF_VAR(prefix, 0989); \ + DEF_VAR(prefix, 0990); \ + DEF_VAR(prefix, 0991); \ + DEF_VAR(prefix, 0992); \ + DEF_VAR(prefix, 0993); \ + DEF_VAR(prefix, 0994); \ + DEF_VAR(prefix, 0995); \ + DEF_VAR(prefix, 0996); \ + DEF_VAR(prefix, 0997); \ + DEF_VAR(prefix, 0998); \ + DEF_VAR(prefix, 0999); \ + DEF_VAR(prefix, 1000); \ + DEF_VAR(prefix, 1001); \ + DEF_VAR(prefix, 1002); \ + DEF_VAR(prefix, 1003); \ + DEF_VAR(prefix, 1004); \ + DEF_VAR(prefix, 1005); \ + DEF_VAR(prefix, 1006); \ + DEF_VAR(prefix, 1007); \ + DEF_VAR(prefix, 1008); \ + DEF_VAR(prefix, 1009); \ + DEF_VAR(prefix, 1010); \ + DEF_VAR(prefix, 1011); \ + DEF_VAR(prefix, 1012); \ + DEF_VAR(prefix, 1013); \ + DEF_VAR(prefix, 1014); \ + DEF_VAR(prefix, 1015); \ + DEF_VAR(prefix, 1016); \ + DEF_VAR(prefix, 1017); \ + DEF_VAR(prefix, 1018); \ + DEF_VAR(prefix, 1019); \ + DEF_VAR(prefix, 1020); \ + DEF_VAR(prefix, 1021); \ + DEF_VAR(prefix, 1022); \ + DEF_VAR(prefix, 1023); \ + DEF_VAR(prefix, 1024); diff --git a/ext/opcache/jit/tls/testing/def.c b/ext/opcache/jit/tls/testing/def.c new file mode 100644 index 00000000000..f18d577e278 --- /dev/null +++ b/ext/opcache/jit/tls/testing/def.c @@ -0,0 +1,33 @@ + +/* _tsrm_ls_cache is defined here */ + +#include +#include +#include + +#ifdef NO_SURPLUS +# include "def-vars.h" +DEF_VARS(def); +#endif + +__thread void* _tsrm_ls_cache; + +size_t tsrm_get_ls_cache_tcb_offset(void) { + return 0; +} + +void zend_accel_error(int type, const char *format, ...) { + if (type < 4) { + va_list ap; + va_start(ap, format); + vprintf(format, ap); + va_end(ap); + } +} + +int test(void); + +int decl(void) { + return test(); +} + diff --git a/ext/opcache/jit/tls/testing/main.c b/ext/opcache/jit/tls/testing/main.c new file mode 100644 index 00000000000..75d40ff7888 --- /dev/null +++ b/ext/opcache/jit/tls/testing/main.c @@ -0,0 +1,48 @@ +#include +#include + +#ifdef NO_SURPLUS +# include "def-vars.h" +DEF_VARS(main); +#endif + +__thread int some_tls_var; + +#ifndef DL_DECL +int decl(void); +#endif + +int main(void) { + /* Ensure TLS vars are allocated */ + some_tls_var = 1; + + int (*decl_p)(void); +#ifdef DL_DECL + int flags = RTLD_LAZY | RTLD_GLOBAL; +# ifdef RTLD_DEEPBIND + flags |= RTLD_DEEPBIND; +# endif + void *handle = dlopen("./libdef.so", flags); + if (!handle) { + fprintf(stderr, "dlopen: %s\n", dlerror()); + return 1; + } + + decl_p = (int (*)(void)) dlsym(handle, "decl"); + if (!decl_p) { + fprintf(stderr, "dlsym: %s\n", dlerror()); + return 1; + } +#else + decl_p = decl; +#endif + + int ret = decl_p(); + if (!ret) { + fprintf(stderr, "FAIL\n"); + } else { + fprintf(stderr, "OK\n"); + } + + return !ret; +} diff --git a/ext/opcache/jit/tls/testing/test.sh b/ext/opcache/jit/tls/testing/test.sh new file mode 100755 index 00000000000..c6b003caafd --- /dev/null +++ b/ext/opcache/jit/tls/testing/test.sh @@ -0,0 +1,232 @@ +#!/bin/sh + +set -e +cd "$(dirname "$0")" + +print_test() { + echo "Testing: $1 (CC=$CC LD=$LD CFLAGS=$CFLAGS)" +} + +exe_def_static_user() { + print_test "TLS var defined in executable, used in same object" + + rm -f main + + $CC $CFLAGS -ggdb3 -o tls.o -c $TLSC + $CC $CFLAGS -ggdb3 -o user.o -c user.c + $CC $CFLAGS -ggdb3 -o def.o -c def.c + $CC $CFLAGS $LDFLAGS -ggdb3 -o main main.c def.o user.o tls.o + + ./main +} + +exe_def_shared_user() { + print_test "TLS var defined in executable, used in shared library" + + rm -f main + + $CC $CFLAGS -ggdb3 -fPIC -o tls.o -c $TLSC + $CC $CFLAGS -ggdb3 -fPIC -o user.o -c user.c + $CC $CFLAGS $LDFLAGS -shared -o libuser.so user.o tls.o + + $CC $CFLAGS -ggdb3 -fPIC -o def.o -c def.c + $CC $CFLAGS $LDFLAGS -ggdb3 -fPIC -o main main.c def.o -Wl,-rpath,$(pwd) -L. -luser + + ./main +} + +shared_def_static_user() { + print_test "TLS var defined in shared library, used in same object" + + rm -f main + + $CC $CFLAGS -ggdb3 -fPIC -o tls.o -c $TLSC + $CC $CFLAGS -ggdb3 -fPIC -o user.o -c user.c + $CC $CFLAGS -ggdb3 -fPIC -o def.o -c def.c + $CC $CFLAGS $LDFLAGS -shared -o libdef.so def.o user.o tls.o + + $CC $CFLAGS $LDFLAGS -ggdb3 -fPIC -o main main.c -Wl,-rpath,$(pwd) -L. -ldef + + ./main +} + +shared_def_shared_user() { + print_test "TLS var defined in shared object, used in other shared object" + + rm -f main + + $CC $CFLAGS -ggdb3 -fPIC -o tls.o -c $TLSC + $CC $CFLAGS -ggdb3 -fPIC -o user.o -c user.c + $CC $CFLAGS $LDFLAGS -shared -o libuser.so user.o tls.o + + $CC $CFLAGS -ggdb3 -fPIC -o def.o -c def.c + $CC $CFLAGS $LDFLAGS -shared -o libdef.so def.o -Wl,-rpath,$(pwd) -L. -luser + + $CC $CFLAGS $LDFLAGS -ggdb3 -fPIC -o main main.c -Wl,-rpath,$(pwd) -L. -ldef + + ./main +} + +shared_def_static_user_no_surplus() { + print_test "TLS var defined in shared library, used in same object. Likely no static TLS surplus." + + rm -f main + + $CC $CFLAGS -ggdb3 -fPIC -o tls.o -c $TLSC + $CC $CFLAGS -ggdb3 -fPIC -o user.o -c user.c + $CC $CFLAGS -DNO_SURPLUS -ggdb3 -fPIC -o def.o -c def.c + $CC $CFLAGS $LDFLAGS -shared -o libdef.so def.o tls.o user.o + + $CC $CFLAGS -DNO_SURPLUS $LDFLAGS -ggdb3 -fPIC -o main main.c -Wl,-rpath,$(pwd) -L. -ldef + + ./main +} + +shared_def_shared_user_no_surplus() { + print_test "TLS var defined in shared object, used in other shared object. Likely no static TLS surplus." + + rm -f main + + $CC $CFLAGS -ggdb3 -fPIC -o tls.o -c $TLSC + $CC $CFLAGS -ggdb3 -fPIC -o user.o -c user.c + $CC $CFLAGS $LDFLAGS -shared -o libuser.so user.o tls.o + + $CC $CFLAGS -DNO_SURPLUS -ggdb3 -fPIC -o def.o -c def.c + $CC $CFLAGS $LDFLAGS -shared -o libdef.so def.o -Wl,-rpath,$(pwd) -L. -luser + + $CC $CFLAGS -DNO_SURPLUS $LDFLAGS -ggdb3 -fPIC -o main main.c -Wl,-rpath,$(pwd) -L. -ldef + + ./main +} + +dl_def_static_user() { + print_test "TLS var defined in dl()'ed object, used in same object" + + rm -f main + + $CC $CFLAGS -ggdb3 -fPIC -o tls.o -c $TLSC + $CC $CFLAGS -ggdb3 -fPIC -o user.o -c user.c + $CC $CFLAGS -ggdb3 -fPIC -o def.o -c def.c + $CC $CFLAGS $LDFLAGS -shared -o libdef.so def.o user.o tls.o + + $CC $CFLAGS $LDFLAGS -DDL_DECL -ggdb3 -fPIC -o main main.c + + ./main +} + +dl_def_shared_user() { + print_test "TLS var defined in dl()'ed object, used in other shared object" + + rm -f main + + $CC $CFLAGS -ggdb3 -fPIC -o tls.o -c $TLSC + $CC $CFLAGS -ggdb3 -fPIC -o user.o -c user.c + $CC $CFLAGS $LDFLAGS -shared -o libuser.so user.o tls.o + + $CC $CFLAGS -ggdb3 -fPIC -o def.o -c def.c + $CC $CFLAGS $LDFLAGS -shared -o libdef.so def.o -Wl,-rpath,$(pwd) -L. -luser + + $CC $CFLAGS $LDFLAGS -DDL_DECL -ggdb3 -fPIC -o main main.c + + ./main +} + +dl_def_static_user_no_surplus() { + print_test "TLS var defined in dl()'ed object, used in same object. Likely no surplus TLS" + + rm -f main + + $CC $CFLAGS -ggdb3 -fPIC -o tls.o -c $TLSC + $CC $CFLAGS -ggdb3 -fPIC -o user.o -c user.c + $CC $CFLAGS -DNO_SURPLUS -ggdb3 -fPIC -o def.o -c def.c + $CC $CFLAGS $LDFLAGS -shared -o libdef.so def.o user.o tls.o + + $CC $CFLAGS -DNO_SURPLUS $LDFLAGS -DDL_DECL -ggdb3 -fPIC -o main main.c + + ./main +} + +dl_def_shared_user_no_surplus() { + print_test "TLS var defined in dl()'ed object, used in other shared object. Likely no surplus TLS" + + rm -f main + + $CC $CFLAGS -ggdb3 -fPIC -o tls.o -c $TLSC + $CC $CFLAGS -ggdb3 -fPIC -o user.o -c user.c + $CC $CFLAGS $LDFLAGS -shared -o libuser.so user.o tls.o + + $CC $CFLAGS -DNO_SURPLUS -ggdb3 -fPIC -o def.o -c def.c + $CC $CFLAGS $LDFLAGS -shared -o libdef.so def.o -Wl,-rpath,$(pwd) -L. -luser + + $CC $CFLAGS -DNO_SURPLUS $LDFLAGS -DDL_DECL -ggdb3 -fPIC -o main main.c + + ./main +} + +if [ -z "$TLSC" ]; then + echo "Variable TLSC is not set" >&2 + exit 1 +fi + +root=$(pwd)/../../../../.. + +# Cheap musl detection +if test -f /etc/alpine-release; then + MUSL="$CFLAGS -D__MUSL__" +else + MUSL= +fi + +if [ "${STATIC_SUPPORT:-yes}" = "yes" ]; then + STATIC=-static +fi + +for CC in clang gcc; do + if [ $CC = gcc ] && [ -f /etc/freebsd-update.conf ]; then + RPATH=-Wl,-rpath,/usr/local/lib/gcc13 + else + RPATH= + fi + case $CC in + gcc) + LDs="" + for l in bdf gold; do + if command -v ld.$l >/dev/null 2>&1; then + LDs="$LDs $l" + fi + done + if [ -z "$LDs" ]; then + LDs=ld + fi + ;; + clang) + LDs="ld" + if command -v ld.lld >/dev/null 2>&1; then + LDs="$LDs lld" + fi + ;; + esac + for LD in $LDs; do + for opt in -O0 -O3; do + CFLAGS="$MACHINE $MUSL $opt -Werror -I$root/ext/opcache -I$root/Zend -I$root" + LDFLAGS="$MACHINE -fuse-ld=$LD $RPATH" + + for pic in "-fPIC" "-fno-PIC $STATIC"; do + CFLAGS="$CFLAGS $pic" exe_def_static_user + done + shared_def_static_user + shared_def_static_user_no_surplus + dl_def_static_user + dl_def_static_user_no_surplus + if [ "$EXTERN_TLS_SUPPORT" = yes ]; then + exe_def_shared_user + shared_def_shared_user + shared_def_shared_user_no_surplus + dl_def_shared_user + dl_def_shared_user_no_surplus + fi + done + done +done + +echo "All OK" >&2 diff --git a/ext/opcache/jit/tls/testing/user.c b/ext/opcache/jit/tls/testing/user.c new file mode 100644 index 00000000000..c27e608f3f4 --- /dev/null +++ b/ext/opcache/jit/tls/testing/user.c @@ -0,0 +1,28 @@ + +/* _tsrm_ls_cache is used / inspected here */ + +#include "../zend_jit_tls.h" + +extern __thread void* _tsrm_ls_cache; + +int test(void) +{ + size_t tcb_offset = 0; + size_t module_index = -1; + size_t module_offset = -1; + + /* Ensure the slot is allocated */ + _tsrm_ls_cache = NULL; + + zend_result result = zend_jit_resolve_tsrm_ls_cache_offsets( + &tcb_offset, &module_index, &module_offset); + + printf("tcb_offset: %zd; module_index: %zd; module_offset: %zd\n", + tcb_offset, module_index, module_offset); + + if (result != SUCCESS) { + return 0; + } + + return zend_jit_tsrm_ls_cache_address(tcb_offset, module_index, module_offset) == &_tsrm_ls_cache; +} diff --git a/ext/opcache/jit/tls/zend_jit_tls.h b/ext/opcache/jit/tls/zend_jit_tls.h new file mode 100644 index 00000000000..5f904292672 --- /dev/null +++ b/ext/opcache/jit/tls/zend_jit_tls.h @@ -0,0 +1,40 @@ +/* + * +----------------------------------------------------------------------+ + * | Zend JIT | + * +----------------------------------------------------------------------+ + * | Copyright (c) The PHP Group | + * +----------------------------------------------------------------------+ + * | This source file is subject to version 3.01 of the PHP license, | + * | that is bundled with this package in the file LICENSE, and is | + * | available through the world-wide-web at the following url: | + * | https://www.php.net/license/3_01.txt | + * | If you did not receive a copy of the PHP license and are unable to | + * | obtain it through the world-wide-web, please send a note to | + * | license@php.net so we can mail you a copy immediately. | + * +----------------------------------------------------------------------+ + * | Authors: Arnaud Le Blanc | + * +----------------------------------------------------------------------+ + */ + +#ifndef ZEND_JIT_TLS_H +#define ZEND_JIT_TLS_H + +#include "Zend/zend_types.h" + +#include +#include + +zend_result zend_jit_resolve_tsrm_ls_cache_offsets( + size_t *tcb_offset, + size_t *module_index, + size_t *module_offset +); + +/* Used for testing */ +void *zend_jit_tsrm_ls_cache_address( + size_t tcb_offset, + size_t module_index, + size_t module_offset +); + +#endif /* ZEND_JIT_TLS_H */ diff --git a/ext/opcache/jit/tls/zend_jit_tls_aarch64.c b/ext/opcache/jit/tls/zend_jit_tls_aarch64.c new file mode 100644 index 00000000000..2dc82221e9c --- /dev/null +++ b/ext/opcache/jit/tls/zend_jit_tls_aarch64.c @@ -0,0 +1,255 @@ +/* + * +----------------------------------------------------------------------+ + * | Zend JIT | + * +----------------------------------------------------------------------+ + * | Copyright (c) The PHP Group | + * +----------------------------------------------------------------------+ + * | This source file is subject to version 3.01 of the PHP license, | + * | that is bundled with this package in the file LICENSE, and is | + * | available through the world-wide-web at the following url: | + * | https://www.php.net/license/3_01.txt | + * | If you did not receive a copy of the PHP license and are unable to | + * | obtain it through the world-wide-web, please send a note to | + * | license@php.net so we can mail you a copy immediately. | + * +----------------------------------------------------------------------+ + * | Authors: Arnaud Le Blanc | + * +----------------------------------------------------------------------+ + */ + +#include "Zend/zend_portability.h" +#include "Zend/zend_types.h" +#include "TSRM/TSRM.h" +#include "zend_accelerator_debug.h" + +#include +#include + +TSRMLS_CACHE_EXTERN(); + +/* https://developer.arm.com/documentation/ddi0602/2025-03/Base-Instructions/ADRP--Form-PC-relative-address-to-4KB-page- */ +#define AARCH64_ADRP_IMM_MASK 0x60ffffe0 /* bits 30-29, 23-5 */ +#define AARCH64_ADRP_IMMHI_MASK 0x00ffffe0 /* bits 23-5 */ +#define AARCH64_ADRP_IMMLO_MASK 0x60000000 /* bits 30-29 */ +#define AARCH64_ADRP_IMMHI_START 5 +#define AARCH64_ADRP_IMMLO_START 29 +#define AARCH64_ADRP_IMMLO_WIDTH 2 + +#define AARCH64_LDR_UNSIGNED_IMM_MASK 0x003ffc00 /* bits 21-10 */ +#define AARCH64_ADD_IMM_MASK 0x003ffc00 /* bits 21-10 */ +#define AARCH64_MOVZ_IMM_MASK 0x001fffe0 /* bits 20-5 */ +#define AARCH64_MOVZ_HW_MASK 0x00600000 /* bits 22-21 */ +#define AARCH64_MOVK_IMM_MASK 0x001fffe0 /* bits 20-5 */ +#define AARCH64_MOVK_HW_MASK 0x00600000 /* bits 22-21 */ +#define AARCH64_NOP 0xd503201f + +#undef USE_FALLBACK + +#ifdef __MUSL__ + +# define DTV_OFFSET -8 +# define DTV_INDEX_GAP 0 + +typedef struct _dtv_pointer_t { + uintptr_t val; +} dtv_pointer_t; + +typedef struct _tls_descriptor { + size_t index; + size_t offset; +} tls_descriptor; + +#elif defined(__FreeBSD__) + +# define DTV_OFFSET 0 +/* Index is offset by 1 on FreeBSD (https://github.com/freebsd/freebsd-src/blob/22ca6db50f4e6bd75a141f57cf953d8de6531a06/lib/libc/gen/tls.c#L88) */ +# define DTV_INDEX_GAP 1 + +typedef struct _dtv_pointer_t { + uintptr_t val; +} dtv_pointer_t; + +/* https://github.com/freebsd/freebsd-src/blob/c52ca7dd09066648b1cc40f758289404d68ab886/libexec/rtld-elf/aarch64/reloc.c#L180-L184 */ +typedef struct _tls_descriptor { + void* thunk; + int index; + size_t offset; +} tls_descriptor; + +#elif defined(__GLIBC__) + +# define DTV_OFFSET 0 +# define DTV_INDEX_GAP 0 + +typedef struct _dtv_pointer_t { + uintptr_t val; + uintptr_t _; +} dtv_pointer_t; + +typedef struct _tls_descriptor { + size_t index; + size_t offset; +} tls_descriptor; + +#else +# define USE_FALLBACK 1 +#endif + +zend_result zend_jit_resolve_tsrm_ls_cache_offsets( + size_t *tcb_offset, + size_t *module_index, + size_t *module_offset +) { +#ifdef USE_FALLBACK + return FAILURE; +#else + *tcb_offset = tsrm_get_ls_cache_tcb_offset(); + if (*tcb_offset != 0) { + return SUCCESS; + } + + void *addr; + uint32_t *insn; + void *thread_pointer; + + __asm__ __volatile__( + /* Load thread pointer address */ + "mrs %0, tpidr_el0\n" + /* Load next instruction address */ + "adr %1, .+4\n\t" + /* General Dynamic code sequence as expected by linkers */ + "adrp x0, :tlsdesc:_tsrm_ls_cache\n" + "ldr x1, [x0, #:tlsdesc_lo12:_tsrm_ls_cache]\n" + "add x0, x0, :tlsdesc_lo12:_tsrm_ls_cache\n" + ".tlsdesccall _tsrm_ls_cache\n" + "blr x1\n" + "mrs x8, tpidr_el0\n" + "add %2, x8, x0\n" + : "=r" (thread_pointer), "=r" (insn), "=r" (addr) + : + : "x0", "x1", "x8"); + + ZEND_ASSERT(addr == &_tsrm_ls_cache); + + /* Check if the general dynamic code was relaxed by the linker */ + + // adrp x0, #any + if ((insn[0] & ~AARCH64_ADRP_IMM_MASK) != 0x90000000) { + zend_accel_error(ACCEL_LOG_DEBUG, "adrp insn does not match: 0x%08" PRIx32 "\n", insn[0]); + goto code_changed; + } + + // ldr x1, [x0, #any] + if ((insn[1] & ~AARCH64_LDR_UNSIGNED_IMM_MASK) != 0xf9400001) { + zend_accel_error(ACCEL_LOG_DEBUG, "ldr insn does not match: 0x%08" PRIx32 "\n", insn[1]); + goto code_changed; + } + + // add x0, x0, any + if ((insn[2] & ~AARCH64_ADD_IMM_MASK) != 0x91000000) { + zend_accel_error(ACCEL_LOG_DEBUG, "add insn does not match: 0x%08" PRIx32 "x\n", insn[2]); + goto code_changed; + } + + /* Code is intact, we can extract immediate values */ + + uint64_t adrp_immhi = (uint64_t)((insn[0] & AARCH64_ADRP_IMMHI_MASK) >> AARCH64_ADRP_IMMHI_START); + uint64_t adrp_immlo = (uint64_t)((insn[0] & AARCH64_ADRP_IMMLO_MASK) >> AARCH64_ADRP_IMMLO_START); + uint64_t adrp_imm = ((adrp_immhi << AARCH64_ADRP_IMMLO_WIDTH) | adrp_immlo) << 12; + uint64_t add_imm = (uint64_t)(insn[2] & AARCH64_ADD_IMM_MASK) >> 10; + uint64_t pc = (uint64_t)insn; + uintptr_t **where = (uintptr_t**)((pc & ~(4096-1)) + adrp_imm + add_imm); + + /* See https://github.com/ARM-software/abi-aa/blob/2a70c42d62e9c3eb5887fa50b71257f20daca6f9/aaelf64/aaelf64.rst + * section "Relocations for thread-local storage". + * The first entry holds a pointer to the variable's TLS descriptor resolver + * function and the second entry holds a platform-specific offset or + * pointer. */ + tls_descriptor *tlsdesc = (tls_descriptor*)(where[1]); + + if ((uintptr_t)&_tsrm_ls_cache - (uintptr_t)thread_pointer == (uintptr_t)tlsdesc) { + zend_accel_error(ACCEL_LOG_DEBUG, "static tls at offset %p from thread pointer (inferred from tlsdesc)\n", tlsdesc); + *tcb_offset = (uintptr_t)tlsdesc; + return SUCCESS; + } + + *module_index = (tlsdesc->index + DTV_INDEX_GAP) * sizeof(dtv_pointer_t); + *module_offset = tlsdesc->offset; + +# if ZEND_DEBUG + /* We've got the TLS descriptor. Double check: */ + + dtv_pointer_t *dtv = *(dtv_pointer_t**)((uintptr_t)thread_pointer + DTV_OFFSET); + addr = (void*)(((dtv_pointer_t*)((char*)dtv + *module_index))->val + *module_offset); + + ZEND_ASSERT(addr == &_tsrm_ls_cache); +# endif + + zend_accel_error(ACCEL_LOG_DEBUG, "dynamic tls module idx %zu offset %zu (inferred from code)\n", (size_t)tlsdesc->index, tlsdesc->offset); + + return SUCCESS; + +code_changed: + + /* Code was changed by the linker. Check if we recognize the updated code */ + + // movz x0, #0, lsl #16 + if ((insn[0] & ~AARCH64_MOVZ_IMM_MASK) != 0xd2a00000) { + zend_accel_error(ACCEL_LOG_DEBUG, "movz insn does not match: 0x%08" PRIx32 "\n", insn[0]); + return FAILURE; + } + + // movk x0, #0x10 + if ((insn[1] & ~AARCH64_MOVK_IMM_MASK) != 0xf2800000) { + zend_accel_error(ACCEL_LOG_DEBUG, "movk insn does not match: 0x%08" PRIx32 "\n", insn[1]); + return FAILURE; + } + + // nop + for (int i = 0; i < 2; i++) { + if (insn[2+i] != AARCH64_NOP) { + zend_accel_error(ACCEL_LOG_DEBUG, "nop(%d) insn does not match: 0x%08" PRIx32 "\n", i, insn[2+i]); + return FAILURE; + } + } + + /* Extract immediate values */ + + uint64_t movz_imm = (insn[0] & AARCH64_MOVZ_IMM_MASK) >> 5; + uint64_t movz_shift = (((insn[0] & AARCH64_MOVZ_HW_MASK) >> 21) << 4); + uint64_t movk_imm = (insn[1] & AARCH64_MOVK_IMM_MASK) >> 5; + uint64_t offset = (movz_imm << movz_shift) | movk_imm; + + if ((uintptr_t)&_tsrm_ls_cache - (uintptr_t)thread_pointer == offset) { + zend_accel_error(ACCEL_LOG_DEBUG, "static tls at offset %" PRIxPTR " from thread pointer (inferred from code)\n", offset); + *tcb_offset = offset; + return SUCCESS; + } + + zend_accel_error(ACCEL_LOG_DEBUG, "static tls offset does not match: %" PRIxPTR " (expected %" PRIxPTR ")\n", + offset, ((uintptr_t)&_tsrm_ls_cache - (uintptr_t)thread_pointer)); + + return FAILURE; +#endif +} + +/* Used for testing */ +void *zend_jit_tsrm_ls_cache_address( + size_t tcb_offset, + size_t module_index, + size_t module_offset +) { + char *thread_pointer; + __asm__ __volatile__( + "mrs %0, tpidr_el0\n" + : "=r" (thread_pointer) + ); + + if (tcb_offset) { + return thread_pointer + tcb_offset; + } + if (module_index != (size_t)-1 && module_offset != (size_t)-1) { + dtv_pointer_t *dtv = *(dtv_pointer_t**)((uintptr_t)thread_pointer + DTV_OFFSET); + return (void*)(((dtv_pointer_t*)((char*)dtv + module_index))->val + module_offset); + } + return NULL; +} diff --git a/ext/opcache/jit/tls/zend_jit_tls_darwin.c b/ext/opcache/jit/tls/zend_jit_tls_darwin.c new file mode 100644 index 00000000000..47a2f01a5a0 --- /dev/null +++ b/ext/opcache/jit/tls/zend_jit_tls_darwin.c @@ -0,0 +1,82 @@ +/* + * +----------------------------------------------------------------------+ + * | Zend JIT | + * +----------------------------------------------------------------------+ + * | Copyright (c) The PHP Group | + * +----------------------------------------------------------------------+ + * | This source file is subject to version 3.01 of the PHP license, | + * | that is bundled with this package in the file LICENSE, and is | + * | available through the world-wide-web at the following url: | + * | https://www.php.net/license/3_01.txt | + * | If you did not receive a copy of the PHP license and are unable to | + * | obtain it through the world-wide-web, please send a note to | + * | license@php.net so we can mail you a copy immediately. | + * +----------------------------------------------------------------------+ + * | Authors: Dmitry Stogov | + * +----------------------------------------------------------------------+ + */ + +#include "Zend/zend_portability.h" +#include "Zend/zend_types.h" +#include "TSRM/TSRM.h" +#include "zend_accelerator_debug.h" + +#include +#include + +TSRMLS_CACHE_EXTERN(); + +zend_result zend_jit_resolve_tsrm_ls_cache_offsets( + size_t *tcb_offset, + size_t *module_index, + size_t *module_offset +) { + *tcb_offset = tsrm_get_ls_cache_tcb_offset(); + if (*tcb_offset != 0) { + return SUCCESS; + } + +#if defined(__x86_64__) + size_t *ti; + __asm__ __volatile__( + "leaq __tsrm_ls_cache(%%rip),%0" + : "=r" (ti)); + *module_offset = ti[2]; + *module_index = ti[1] * 8; + + return SUCCESS; +#endif + + return FAILURE; +} + +/* Used for testing */ +void *zend_jit_tsrm_ls_cache_address( + size_t tcb_offset, + size_t module_index, + size_t module_offset +) { + +#if defined(__x86_64__) + if (tcb_offset) { + char *addr; + __asm__ __volatile__( + "movq %%gs:(%1), %0\n" + : "=r" (addr) + : "r" (tcb_offset) + ); + return addr; + } + if (module_index != (size_t)-1 && module_offset != (size_t)-1) { + char *base; + __asm__ __volatile__( + "movq %%gs:(%1), %0\n" + : "=r" (base) + : "r" (module_index) + ); + return base + module_offset; + } +#endif + + return NULL; +} diff --git a/ext/opcache/jit/tls/zend_jit_tls_win.c b/ext/opcache/jit/tls/zend_jit_tls_win.c new file mode 100644 index 00000000000..23f0c1e79ba --- /dev/null +++ b/ext/opcache/jit/tls/zend_jit_tls_win.c @@ -0,0 +1,64 @@ +/* + * +----------------------------------------------------------------------+ + * | Zend JIT | + * +----------------------------------------------------------------------+ + * | Copyright (c) The PHP Group | + * +----------------------------------------------------------------------+ + * | This source file is subject to version 3.01 of the PHP license, | + * | that is bundled with this package in the file LICENSE, and is | + * | available through the world-wide-web at the following url: | + * | https://www.php.net/license/3_01.txt | + * | If you did not receive a copy of the PHP license and are unable to | + * | obtain it through the world-wide-web, please send a note to | + * | license@php.net so we can mail you a copy immediately. | + * +----------------------------------------------------------------------+ + * | Authors: Dmitry Stogov | + * +----------------------------------------------------------------------+ + */ + +#include "Zend/zend_portability.h" +#include "Zend/zend_types.h" +#include "TSRM/TSRM.h" +#include "zend_accelerator_debug.h" + +#include +#include + +TSRMLS_CACHE_EXTERN(); + +extern uint32_t _tls_index; +extern char *_tls_start; +extern char *_tls_end; + +zend_result zend_jit_resolve_tsrm_ls_cache_offsets( + size_t *tcb_offset, + size_t *module_index, + size_t *module_offset +) { + /* To find offset of "_tsrm_ls_cache" in TLS segment we perform a linear scan of local TLS memory */ + /* Probably, it might be better solution */ +#ifdef _WIN64 + void ***tls_mem = ((void****)__readgsqword(0x58))[_tls_index]; +#else + void ***tls_mem = ((void****)__readfsdword(0x2c))[_tls_index]; +#endif + void *val = _tsrm_ls_cache; + size_t offset = 0; + size_t size = (char*)&_tls_end - (char*)&_tls_start; + + while (offset < size) { + if (*tls_mem == val) { + *module_index = _tls_index * sizeof(void*); + *module_offset = offset; + return SUCCESS; + } + tls_mem++; + offset += sizeof(void*); + } + + if (offset >= size) { + zend_accel_error_noreturn(ACCEL_LOG_FATAL, "Could not enable JIT: offset >= size"); + } + + return FAILURE; +} diff --git a/ext/opcache/jit/tls/zend_jit_tls_x86.c b/ext/opcache/jit/tls/zend_jit_tls_x86.c new file mode 100644 index 00000000000..bca46c8f826 --- /dev/null +++ b/ext/opcache/jit/tls/zend_jit_tls_x86.c @@ -0,0 +1,239 @@ +/* + * +----------------------------------------------------------------------+ + * | Zend JIT | + * +----------------------------------------------------------------------+ + * | Copyright (c) The PHP Group | + * +----------------------------------------------------------------------+ + * | This source file is subject to version 3.01 of the PHP license, | + * | that is bundled with this package in the file LICENSE, and is | + * | available through the world-wide-web at the following url: | + * | https://www.php.net/license/3_01.txt | + * | If you did not receive a copy of the PHP license and are unable to | + * | obtain it through the world-wide-web, please send a note to | + * | license@php.net so we can mail you a copy immediately. | + * +----------------------------------------------------------------------+ + * | Authors: Arnaud Le Blanc | + * +----------------------------------------------------------------------+ + */ + +#include "zend_portability.h" +#include "zend_types.h" +#include "TSRM/TSRM.h" +#include "zend_accelerator_debug.h" +#include "zend_jit_tls.h" + +#include +#include + +TSRMLS_CACHE_EXTERN(); + +#undef USE_FALLBACK + +#ifdef __MUSL__ + +# define DTV_OFFSET 4 +# define DTV_INDEX_GAP 0 + +typedef struct _dtv_pointer_t { + uintptr_t val; +} dtv_pointer_t; + +typedef struct _tls_descriptor { + size_t index; + size_t offset; +} tls_descriptor; + +#elif defined(__FreeBSD__) + +# define DTV_OFFSET 4 +# define DTV_INDEX_GAP 1 + +typedef struct _dtv_pointer_t { + uintptr_t val; +} dtv_pointer_t; + +/* https://github.com/freebsd/freebsd-src/blob/6b94546a7ea2dc593f5765bd5465a8b7bb80c325/libexec/rtld-elf/i386/rtld_machdep.h#L65 */ +typedef struct _tls_descriptor { + unsigned long index; + unsigned long offset; +} tls_descriptor; + +#elif defined(__GLIBC__) + +# define DTV_OFFSET 4 +# define DTV_INDEX_GAP 0 + +typedef struct _dtv_pointer_t { + uintptr_t val; + uintptr_t _; +} dtv_pointer_t; + +typedef struct _tls_descriptor { + size_t index; + size_t offset; +} tls_descriptor; + +#else +# define USE_FALLBACK 1 +#endif + +zend_result zend_jit_resolve_tsrm_ls_cache_offsets( + size_t *tcb_offset, + size_t *module_index, + size_t *module_offset +) { +#ifdef USE_FALLBACK + return FAILURE; +#else + *tcb_offset = tsrm_get_ls_cache_tcb_offset(); + if (*tcb_offset != 0) { + return SUCCESS; + } + + void *t_addr; + unsigned char *code; + void *thread_pointer; + + __asm__ __volatile__( + /* Load next instruction address */ + "call 1f\n" + ".subsection 1\n" + "1:\n" + "movl (%%esp), %%ebx\n" + "movl %%ebx, %%esi\n" + "ret\n" + ".previous\n" + /* General Dynamic code sequence as expected by linkers */ + "addl $_GLOBAL_OFFSET_TABLE_, %%ebx\n" + "leal _tsrm_ls_cache@TLSGD(,%%ebx,1), %%eax\n" + "call ___tls_get_addr@PLT\n" + /* Load thread pointer address */ + "movl %%gs:0, %%ebx\n" + : "=a" (t_addr), "=S" (code), "=b" (thread_pointer) + ); + + ZEND_ASSERT(t_addr == &_tsrm_ls_cache); + + /* Check if the general dynamic code was relaxed by the linker */ + + // addl any,%ebx + if (memcmp(&code[0], "\x81\xc3", 2) != 0) { + uint64_t bytes; + memcpy(&bytes, &code[0], 8); + zend_accel_error(ACCEL_LOG_DEBUG, "addl insn does not match: 0x%16" PRIx64 "\n", bytes); + goto code_changed; + } + + // leal any(,%ebx,1),%eax + if (memcmp(&code[6], "\x8d\x04\x1d", 3) != 0) { + uint64_t bytes; + memcpy(&bytes, &code[6], 8); + zend_accel_error(ACCEL_LOG_DEBUG, "leal insn does not match: 0x%16" PRIx64 "\n", bytes); + goto code_changed; + } + + // call any + if (memcmp(&code[13], "\xe8", 1) != 0) { + uint64_t bytes; + memcpy(&bytes, &code[13], 8); + zend_accel_error(ACCEL_LOG_DEBUG, "call insn does not match: 0x%16" PRIx64 "\n", bytes); + goto code_changed; + } + + /* Code is intact, we can extract immediate values */ + + uint32_t addl_imm = ((uint32_t)code[5] << 24) + | ((uint32_t)code[4] << 16) + | ((uint32_t)code[3] << 8) + | ((uint32_t)code[2]); + uint32_t leal_imm = ((uint32_t)code[12] << 24) + | ((uint32_t)code[11] << 16) + | ((uint32_t)code[10] << 8) + | ((uint32_t)code[9]); + + tls_descriptor *tlsdesc = (tls_descriptor*)(leal_imm + addl_imm + (uintptr_t)code); + + *module_index = (tlsdesc->index + DTV_INDEX_GAP) * sizeof(dtv_pointer_t); + *module_offset = tlsdesc->offset; + +# if ZEND_DEBUG + /* We've got the TLS descriptor. Double check: */ + + dtv_pointer_t *dtv = *(dtv_pointer_t**)((uintptr_t)thread_pointer + DTV_OFFSET); + void *addr = (void*)(((dtv_pointer_t*)((char*)dtv + *module_index))->val + *module_offset); + + ZEND_ASSERT(addr == &_tsrm_ls_cache); +# endif + + zend_accel_error(ACCEL_LOG_DEBUG, "dynamic tls module idx %zu offset %zu (inferred from code)\n", + (size_t)tlsdesc->index, (size_t)tlsdesc->offset); + + return SUCCESS; + +code_changed: + + /* Code was changed by the linker. Check if we recognize the updated code */ + + /* + * 81 c3 98 2d 00 00 addl $0x2d98,%ebx + * 65 a1 00 00 00 00 movl %gs:0x0,%eax + * 81 e8 04 00 00 00 subl $0x4,%eax + */ + + // movl %gs:0x0,%eax + if (memcmp(&code[6], "\x65\xa1\x00\x00\x00\x00", 6) != 0) { + uint64_t bytes; + memcpy(&bytes, &code[6], 8); + zend_accel_error(ACCEL_LOG_DEBUG, "movl insn does not match: 0x%16" PRIx64 "\n", bytes); + return FAILURE; + } + + // subl $any,%eax + if (memcmp(&code[12], "\x81\xe8", 2) != 0) { + uint64_t bytes; + memcpy(&bytes, &code[6], 8); + zend_accel_error(ACCEL_LOG_DEBUG, "subl insn does not match: 0x%16" PRIx64 "\n", bytes); + return FAILURE; + } + + /* Extract immediate values */ + + uint32_t offset = -(((uint32_t)code[17] << 24) + | ((uint32_t)code[16] << 16) + | ((uint32_t)code[15] << 8) + | ((uint32_t)code[14])); + + if ((uintptr_t)&_tsrm_ls_cache - (uintptr_t)thread_pointer == offset) { + zend_accel_error(ACCEL_LOG_DEBUG, "static tls at offset %" PRIx32 " from thread pointer (inferred from code)\n", offset); + *tcb_offset = offset; + return SUCCESS; + } + + zend_accel_error(ACCEL_LOG_DEBUG, "static tls offset does not match: 0x%" PRIx32 " (expected 0x%" PRIx32 ")\n", + offset, (uint32_t)((uintptr_t)&_tsrm_ls_cache - (uintptr_t)thread_pointer)); + + return FAILURE; +#endif +} + +/* Used for testing */ +void *zend_jit_tsrm_ls_cache_address( + size_t tcb_offset, + size_t module_index, + size_t module_offset +) { + char *thread_pointer; + __asm__ __volatile__( + "movl %%gs:0, %0\n" + : "=r" (thread_pointer) + ); + + if (tcb_offset) { + return thread_pointer + tcb_offset; + } + if (module_index != (size_t)-1 && module_offset != (size_t)-1) { + dtv_pointer_t *dtv = *(dtv_pointer_t**)((uintptr_t)thread_pointer + DTV_OFFSET); + return (void*)(((dtv_pointer_t*)((char*)dtv + module_index))->val + module_offset); + } + return NULL; +} diff --git a/ext/opcache/jit/tls/zend_jit_tls_x86_64.c b/ext/opcache/jit/tls/zend_jit_tls_x86_64.c new file mode 100644 index 00000000000..3adeb1ff806 --- /dev/null +++ b/ext/opcache/jit/tls/zend_jit_tls_x86_64.c @@ -0,0 +1,222 @@ +/* + * +----------------------------------------------------------------------+ + * | Zend JIT | + * +----------------------------------------------------------------------+ + * | Copyright (c) The PHP Group | + * +----------------------------------------------------------------------+ + * | This source file is subject to version 3.01 of the PHP license, | + * | that is bundled with this package in the file LICENSE, and is | + * | available through the world-wide-web at the following url: | + * | https://www.php.net/license/3_01.txt | + * | If you did not receive a copy of the PHP license and are unable to | + * | obtain it through the world-wide-web, please send a note to | + * | license@php.net so we can mail you a copy immediately. | + * +----------------------------------------------------------------------+ + * | Authors: Arnaud Le Blanc | + * +----------------------------------------------------------------------+ + */ + +#include "zend_portability.h" +#include "zend_types.h" +#include "TSRM/TSRM.h" +#include "zend_accelerator_debug.h" +#include "zend_jit_tls.h" + +#include +#include + +TSRMLS_CACHE_EXTERN(); + +#undef USE_FALLBACK + +#ifdef __MUSL__ + +# define DTV_OFFSET 8 +# define DTV_INDEX_GAP 0 + +typedef struct _dtv_pointer_t { + uintptr_t val; +} dtv_pointer_t; + +typedef struct _tls_descriptor { + size_t index; + size_t offset; +} tls_descriptor; + +#elif defined(__FreeBSD__) + +# define DTV_OFFSET 8 +# define DTV_INDEX_GAP 1 + +typedef struct _dtv_pointer_t { + uintptr_t val; +} dtv_pointer_t; + +/* https://github.com/freebsd/freebsd-src/blob/6b94546a7ea2dc593f5765bd5465a8b7bb80c325/libexec/rtld-elf/amd64/rtld_machdep.h#L65 */ +typedef struct _tls_descriptor { + unsigned long index; + unsigned long offset; +} tls_descriptor; + +#elif defined(__GLIBC__) + +# define DTV_OFFSET 8 +# define DTV_INDEX_GAP 0 + +typedef struct _dtv_pointer_t { + uintptr_t val; + uintptr_t _; +} dtv_pointer_t; + +typedef struct _tls_descriptor { + size_t index; + size_t offset; +} tls_descriptor; + +#else +# define USE_FALLBACK 1 +#endif + +zend_result zend_jit_resolve_tsrm_ls_cache_offsets( + size_t *tcb_offset, + size_t *module_index, + size_t *module_offset +) { +#ifdef USE_FALLBACK + return FAILURE; +#else + *tcb_offset = tsrm_get_ls_cache_tcb_offset(); + if (*tcb_offset != 0) { + return SUCCESS; + } + + void *addr; + unsigned char *code; + void *thread_pointer; + + __asm__ __volatile__( + /* Load next instruction address */ + "leaq (%%rip), %%rbx\n" + /* General Dynamic code sequence as expected by linkers */ + ".byte 0x66\n" + "leaq _tsrm_ls_cache@tlsgd(%%rip), %%rdi\n" + ".word 0x6666\n" + "rex64\n" + "call __tls_get_addr\n" + /* Load thread pointer address */ + "movq %%fs:0, %%rsi\n" + : "=a" (addr), "=b" (code), "=S" (thread_pointer) + ); + + ZEND_ASSERT(addr == &_tsrm_ls_cache); + + /* Check if the general dynamic code was relaxed by the linker */ + + // data16 leaq any(%rip),%rdi + if (memcmp(&code[0], "\x66\x48\x8d\x3d", 4) != 0) { + uint64_t bytes; + memcpy(&bytes, &code[0], 8); + zend_accel_error(ACCEL_LOG_DEBUG, "leaq insn does not match: 0x%016" PRIx64 "\n", bytes); + goto code_changed; + } + + // data16 data16 rex.W call any + if (memcmp(&code[8], "\x66\x66\x48\xe8", 4) != 0) { + uint64_t bytes; + memcpy(&bytes, &code[8], 8); + zend_accel_error(ACCEL_LOG_DEBUG, "call insn does not match: 0x%016" PRIx64 "\n", bytes); + goto code_changed; + } + + /* Code is intact, we can extract immediate values */ + + uintptr_t leaq_imm = (uintptr_t)(int32_t)((uint32_t)code[7] << 24) + | ((uint32_t)code[6] << 16) + | ((uint32_t)code[5] << 8) + | ((uint32_t)code[4]); + + tls_descriptor *tlsdesc = (tls_descriptor*)(leaq_imm + (uintptr_t)code + 8 /* leaq */); + + *module_index = ((size_t)tlsdesc->index + DTV_INDEX_GAP) * sizeof(dtv_pointer_t); + *module_offset = (size_t)tlsdesc->offset; + +# if ZEND_DEBUG + /* We've got the TLS descriptor. Double check: */ + + dtv_pointer_t *dtv = *(dtv_pointer_t**)((uintptr_t)thread_pointer + DTV_OFFSET); + addr = (void*)(((dtv_pointer_t*)((char*)dtv + *module_index))->val + *module_offset); + + ZEND_ASSERT(addr == &_tsrm_ls_cache); +# endif + + zend_accel_error(ACCEL_LOG_DEBUG, "dynamic tls module idx %zu offset %zu (inferred from code)\n", + (size_t)tlsdesc->index, (size_t)tlsdesc->offset); + + return SUCCESS; + +code_changed: + + /* Code was changed by the linker. Check if we recognize the updated code */ + + /* + * 64 48 8b 04 25 00 00 00 00 movq %fs:0x0,%rax + * 48 8d 80 f8 ff ff ff leaq -0x8(%rax),%rax + */ + + // movq %fs:0x0,%rax + if (memcmp(&code[0], "\x64\x48\x8b\x04\x25\x00\x00\x00\x00", 9) != 0) { + uint64_t bytes; + memcpy(&bytes, &code[0], 8); + zend_accel_error(ACCEL_LOG_DEBUG, "movq insn does not match: 0x%016" PRIx64 "\n", bytes); + return FAILURE; + } + + // leaq any(%rax),$rax + if (memcmp(&code[9], "\x48\x8d\x80", 3) != 0) { + uint64_t bytes; + memcpy(&bytes, &code[10], 8); + zend_accel_error(ACCEL_LOG_DEBUG, "leaq insn does not match: 0x%016" PRIx64 "\n", bytes); + return FAILURE; + } + + /* Extract immediate values */ + + uintptr_t offset = (uintptr_t)(int32_t)(((uint32_t)code[15] << 24) + | ((uint32_t)code[14] << 16) + | ((uint32_t)code[13] << 8) + | ((uint32_t)code[12])); + + if ((uintptr_t)&_tsrm_ls_cache - (uintptr_t)thread_pointer == offset) { + *tcb_offset = offset; + zend_accel_error(ACCEL_LOG_DEBUG, "static tls at offset %" PRIxPTR " from thread pointer (inferred from code)\n", offset); + return SUCCESS; + } + + zend_accel_error(ACCEL_LOG_DEBUG, "static tls offset does not match: %" PRIxPTR " (expected %" PRIxPTR ")\n", + offset, ((uintptr_t)&_tsrm_ls_cache - (uintptr_t)thread_pointer)); + + return FAILURE; +#endif +} + +/* Used for testing */ +void *zend_jit_tsrm_ls_cache_address( + size_t tcb_offset, + size_t module_index, + size_t module_offset +) { + char *thread_pointer; + __asm__ __volatile__( + "movq %%fs:0, %0\n" + : "=r" (thread_pointer) + ); + + if (tcb_offset) { + return thread_pointer + tcb_offset; + } + if (module_index != (size_t)-1 && module_offset != (size_t)-1) { + dtv_pointer_t *dtv = *(dtv_pointer_t**)((uintptr_t)thread_pointer + DTV_OFFSET); + return (void*)(((dtv_pointer_t*)((char*)dtv + module_index))->val + module_offset); + } + return NULL; +} diff --git a/ext/opcache/jit/zend_jit.c b/ext/opcache/jit/zend_jit.c index fa2cc10e8b3..5e3909a1ce2 100644 --- a/ext/opcache/jit/zend_jit.c +++ b/ext/opcache/jit/zend_jit.c @@ -48,6 +48,7 @@ #ifdef ZTS int jit_globals_id; +size_t jit_globals_offset; #else zend_jit_globals jit_globals; #endif @@ -77,7 +78,6 @@ int zend_jit_profile_counter_rid = -1; int16_t zend_jit_hot_counters[ZEND_HOT_COUNTERS_COUNT]; const zend_op *zend_jit_halt_op = NULL; -static int zend_jit_vm_kind = 0; #ifdef HAVE_PTHREAD_JIT_WRITE_PROTECT_NP static int zend_write_protect = 1; #endif @@ -90,13 +90,13 @@ static size_t dasm_size = 0; static zend_long jit_bisect_pos = 0; -static const void *zend_jit_runtime_jit_handler = NULL; -static const void *zend_jit_profile_jit_handler = NULL; -static const void *zend_jit_func_hot_counter_handler = NULL; -static const void *zend_jit_loop_hot_counter_handler = NULL; -static const void *zend_jit_func_trace_counter_handler = NULL; -static const void *zend_jit_ret_trace_counter_handler = NULL; -static const void *zend_jit_loop_trace_counter_handler = NULL; +static zend_vm_opcode_handler_t zend_jit_runtime_jit_handler = NULL; +static zend_vm_opcode_handler_t zend_jit_profile_jit_handler = NULL; +static zend_vm_opcode_handler_t zend_jit_func_hot_counter_handler = NULL; +static zend_vm_opcode_handler_t zend_jit_loop_hot_counter_handler = NULL; +static zend_vm_opcode_handler_t zend_jit_func_trace_counter_handler = NULL; +static zend_vm_opcode_handler_t zend_jit_ret_trace_counter_handler = NULL; +static zend_vm_opcode_handler_t zend_jit_loop_trace_counter_handler = NULL; static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_runtime_jit(ZEND_OPCODE_HANDLER_ARGS); @@ -1417,7 +1417,7 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op zend_jit_ctx ctx; zend_jit_ctx *jit = &ctx; zend_jit_reg_var *ra = NULL; - void *handler; + zend_vm_opcode_handler_t handler; int call_level = 0; void *checkpoint = NULL; bool recv_emitted = 0; /* emitted at least one RECV opcode */ @@ -3213,7 +3213,7 @@ static void zend_jit_setup_hot_counters_ex(zend_op_array *op_array, zend_cfg *cf } } - opline->handler = (const void*)zend_jit_func_hot_counter_handler; + opline->handler = zend_jit_func_hot_counter_handler; } if (JIT_G(hot_loop)) { @@ -3223,7 +3223,7 @@ static void zend_jit_setup_hot_counters_ex(zend_op_array *op_array, zend_cfg *cf if ((cfg->blocks[i].flags & ZEND_BB_REACHABLE) && (cfg->blocks[i].flags & ZEND_BB_LOOP_HEADER)) { op_array->opcodes[cfg->blocks[i].start].handler = - (const void*)zend_jit_loop_hot_counter_handler; + zend_jit_loop_hot_counter_handler; } } } @@ -3316,7 +3316,7 @@ int zend_jit_op_array(zend_op_array *op_array, zend_script *script) jit_extension->op_array = op_array; jit_extension->orig_handler = (void*)opline->handler; ZEND_SET_FUNC_INFO(op_array, (void*)jit_extension); - opline->handler = (const void*)zend_jit_runtime_jit_handler; + opline->handler = zend_jit_runtime_jit_handler; zend_shared_alloc_register_xlat_entry(op_array->opcodes, jit_extension); return SUCCESS; @@ -3346,7 +3346,7 @@ int zend_jit_op_array(zend_op_array *op_array, zend_script *script) jit_extension->op_array = op_array; jit_extension->orig_handler = (void*)opline->handler; ZEND_SET_FUNC_INFO(op_array, (void*)jit_extension); - opline->handler = (const void*)zend_jit_profile_jit_handler; + opline->handler = zend_jit_profile_jit_handler; zend_shared_alloc_register_xlat_entry(op_array->opcodes, jit_extension); } @@ -3566,23 +3566,23 @@ void zend_jit_protect(void) static void zend_jit_init_handlers(void) { - if (zend_jit_vm_kind == ZEND_VM_KIND_HYBRID) { - zend_jit_runtime_jit_handler = zend_jit_stub_handlers[jit_stub_hybrid_runtime_jit]; - zend_jit_profile_jit_handler = zend_jit_stub_handlers[jit_stub_hybrid_profile_jit]; - zend_jit_func_hot_counter_handler = zend_jit_stub_handlers[jit_stub_hybrid_func_hot_counter]; - zend_jit_loop_hot_counter_handler = zend_jit_stub_handlers[jit_stub_hybrid_loop_hot_counter]; - zend_jit_func_trace_counter_handler = zend_jit_stub_handlers[jit_stub_hybrid_func_trace_counter]; - zend_jit_ret_trace_counter_handler = zend_jit_stub_handlers[jit_stub_hybrid_ret_trace_counter]; - zend_jit_loop_trace_counter_handler = zend_jit_stub_handlers[jit_stub_hybrid_loop_trace_counter]; - } else { - zend_jit_runtime_jit_handler = (const void*)zend_runtime_jit; - zend_jit_profile_jit_handler = (const void*)zend_jit_profile_helper; - zend_jit_func_hot_counter_handler = (const void*)zend_jit_func_counter_helper; - zend_jit_loop_hot_counter_handler = (const void*)zend_jit_loop_counter_helper; - zend_jit_func_trace_counter_handler = (const void*)zend_jit_func_trace_helper; - zend_jit_ret_trace_counter_handler = (const void*)zend_jit_ret_trace_helper; - zend_jit_loop_trace_counter_handler = (const void*)zend_jit_loop_trace_helper; - } +#if ZEND_VM_KIND == ZEND_VM_KIND_HYBRID + zend_jit_runtime_jit_handler = (zend_vm_opcode_handler_t)zend_jit_stub_handlers[jit_stub_hybrid_runtime_jit]; + zend_jit_profile_jit_handler = (zend_vm_opcode_handler_t)zend_jit_stub_handlers[jit_stub_hybrid_profile_jit]; + zend_jit_func_hot_counter_handler = (zend_vm_opcode_handler_t)zend_jit_stub_handlers[jit_stub_hybrid_func_hot_counter]; + zend_jit_loop_hot_counter_handler = (zend_vm_opcode_handler_t)zend_jit_stub_handlers[jit_stub_hybrid_loop_hot_counter]; + zend_jit_func_trace_counter_handler = (zend_vm_opcode_handler_t)zend_jit_stub_handlers[jit_stub_hybrid_func_trace_counter]; + zend_jit_ret_trace_counter_handler = (zend_vm_opcode_handler_t)zend_jit_stub_handlers[jit_stub_hybrid_ret_trace_counter]; + zend_jit_loop_trace_counter_handler = (zend_vm_opcode_handler_t)zend_jit_stub_handlers[jit_stub_hybrid_loop_trace_counter]; +#else + zend_jit_runtime_jit_handler = zend_runtime_jit; + zend_jit_profile_jit_handler = zend_jit_profile_helper; + zend_jit_func_hot_counter_handler = zend_jit_func_counter_helper; + zend_jit_loop_hot_counter_handler = zend_jit_loop_counter_helper; + zend_jit_func_trace_counter_handler = zend_jit_func_trace_helper; + zend_jit_ret_trace_counter_handler = zend_jit_ret_trace_helper; + zend_jit_loop_trace_counter_handler = zend_jit_loop_trace_helper; +#endif } static void zend_jit_globals_ctor(zend_jit_globals *jit_globals) @@ -3701,25 +3701,20 @@ int zend_jit_debug_config(zend_long old_val, zend_long new_val, int stage) void zend_jit_init(void) { #ifdef ZTS - jit_globals_id = ts_allocate_id(&jit_globals_id, sizeof(zend_jit_globals), (ts_allocate_ctor) zend_jit_globals_ctor, (ts_allocate_dtor) zend_jit_globals_dtor); + jit_globals_id = ts_allocate_fast_id(&jit_globals_id, &jit_globals_offset, sizeof(zend_jit_globals), (ts_allocate_ctor) zend_jit_globals_ctor, (ts_allocate_dtor) zend_jit_globals_dtor); #else zend_jit_globals_ctor(&jit_globals); #endif } +#if ZEND_VM_KIND != ZEND_VM_KIND_CALL && ZEND_VM_KIND != ZEND_VM_KIND_HYBRID +# error JIT is compatible only with CALL and HYBRID VM +#endif + int zend_jit_check_support(void) { int i; - zend_jit_vm_kind = zend_vm_kind(); - if (zend_jit_vm_kind != ZEND_VM_KIND_CALL && - zend_jit_vm_kind != ZEND_VM_KIND_HYBRID) { - zend_error(E_WARNING, "JIT is compatible only with CALL and HYBRID VM. JIT disabled."); - JIT_G(enabled) = 0; - JIT_G(on) = 0; - return FAILURE; - } - if (zend_execute_ex != execute_ex) { if (zend_dtrace_enabled) { zend_error(E_WARNING, "JIT is incompatible with DTrace. JIT disabled."); @@ -3864,6 +3859,14 @@ void zend_jit_shutdown(void) #else zend_jit_trace_free_caches(&jit_globals); #endif + + /* Reset global pointers to prevent use-after-free in `zend_jit_status()` + * after gracefully restarting Apache with mod_php, see: + * https://github.com/php/php-src/pull/19212 */ + dasm_ptr = NULL; + dasm_buf = NULL; + dasm_end = NULL; + dasm_size = 0; } static void zend_jit_reset_counters(void) @@ -3920,8 +3923,10 @@ void zend_jit_deactivate(void) zend_jit_profile_counter = 0; } -static void zend_jit_restart_preloaded_op_array(zend_op_array *op_array) +static void zend_jit_restart_preloaded_op_array(zend_op_array *op_array, void *context) { + ZEND_IGNORE_VALUE(context); + zend_func_info *func_info = ZEND_FUNC_INFO(op_array); if (!func_info) { @@ -3945,37 +3950,17 @@ static void zend_jit_restart_preloaded_op_array(zend_op_array *op_array) } } if (func_info->flags & ZEND_FUNC_JIT_ON_FIRST_EXEC) { - opline->handler = (const void*)zend_jit_runtime_jit_handler; + opline->handler = zend_jit_runtime_jit_handler; } else { - opline->handler = (const void*)zend_jit_profile_jit_handler; + opline->handler = zend_jit_profile_jit_handler; } #endif } - if (op_array->num_dynamic_func_defs) { - for (uint32_t i = 0; i < op_array->num_dynamic_func_defs; i++) { - zend_jit_restart_preloaded_op_array(op_array->dynamic_func_defs[i]); - } - } } static void zend_jit_restart_preloaded_script(zend_persistent_script *script) { - zend_class_entry *ce; - zend_op_array *op_array; - - zend_jit_restart_preloaded_op_array(&script->script.main_op_array); - - ZEND_HASH_MAP_FOREACH_PTR(&script->script.function_table, op_array) { - zend_jit_restart_preloaded_op_array(op_array); - } ZEND_HASH_FOREACH_END(); - - ZEND_HASH_MAP_FOREACH_PTR(&script->script.class_table, ce) { - ZEND_HASH_MAP_FOREACH_PTR(&ce->function_table, op_array) { - if (op_array->type == ZEND_USER_FUNCTION) { - zend_jit_restart_preloaded_op_array(op_array); - } - } ZEND_HASH_FOREACH_END(); - } ZEND_HASH_FOREACH_END(); + zend_foreach_op_array(&script->script, zend_jit_restart_preloaded_op_array, NULL); } void zend_jit_restart(void) diff --git a/ext/opcache/jit/zend_jit.h b/ext/opcache/jit/zend_jit.h index 9178d340a0e..5e6b225676a 100644 --- a/ext/opcache/jit/zend_jit.h +++ b/ext/opcache/jit/zend_jit.h @@ -145,8 +145,9 @@ typedef struct _zend_jit_globals { } zend_jit_globals; #ifdef ZTS -# define JIT_G(v) ZEND_TSRMG(jit_globals_id, zend_jit_globals *, v) +# define JIT_G(v) ZEND_TSRMG_FAST(jit_globals_offset, zend_jit_globals *, v) extern int jit_globals_id; +extern size_t jit_globals_offset; #else # define JIT_G(v) (jit_globals.v) extern zend_jit_globals jit_globals; diff --git a/ext/opcache/jit/zend_jit_internal.h b/ext/opcache/jit/zend_jit_internal.h index 3623689f05a..9ff011d0f99 100644 --- a/ext/opcache/jit/zend_jit_internal.h +++ b/ext/opcache/jit/zend_jit_internal.h @@ -26,6 +26,7 @@ #include "Zend/zend_constants.h" #include "Zend/Optimizer/zend_func_info.h" #include "Zend/Optimizer/zend_call_graph.h" +#include "zend_vm_opcodes.h" /* Address Encoding */ typedef uintptr_t zend_jit_addr; @@ -130,7 +131,7 @@ static zend_always_inline bool zend_jit_same_addr(zend_jit_addr addr1, zend_jit_ typedef struct _zend_jit_op_array_extension { zend_func_info func_info; const zend_op_array *op_array; - const void *orig_handler; + zend_vm_opcode_handler_t orig_handler; } zend_jit_op_array_extension; /* Profiler */ @@ -169,7 +170,7 @@ typedef struct _zend_jit_op_array_hot_extension { zend_func_info func_info; const zend_op_array *op_array; int16_t *counter; - const void *orig_handlers[1]; + zend_vm_opcode_handler_t orig_handlers[1]; } zend_jit_op_array_hot_extension; #define zend_jit_op_array_hash(op_array) \ @@ -225,9 +226,6 @@ extern const zend_op *zend_jit_halt_op; # define ZEND_VM_ENTER_BIT 1ULL #endif -/* VM handlers */ -typedef ZEND_OPCODE_HANDLER_RET (ZEND_FASTCALL *zend_vm_opcode_handler_t)(ZEND_OPCODE_HANDLER_ARGS); - /* VM helpers */ ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_jit_leave_nested_func_helper(ZEND_OPCODE_HANDLER_ARGS_EX uint32_t call_info); ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_jit_leave_top_func_helper(ZEND_OPCODE_HANDLER_ARGS_EX uint32_t call_info); @@ -339,8 +337,8 @@ typedef enum _zend_jit_trace_stop { typedef union _zend_op_trace_info { zend_op dummy; /* the size of this structure must be the same as zend_op */ struct { - const void *orig_handler; - const void *call_handler; + zend_vm_opcode_handler_t orig_handler; + zend_vm_opcode_handler_func_t call_handler; int16_t *counter; uint8_t trace_flags; }; diff --git a/ext/opcache/jit/zend_jit_ir.c b/ext/opcache/jit/zend_jit_ir.c index 6aa78965549..3ed9a511475 100644 --- a/ext/opcache/jit/zend_jit_ir.c +++ b/ext/opcache/jit/zend_jit_ir.c @@ -18,6 +18,7 @@ #include "jit/ir/ir.h" #include "jit/ir/ir_builder.h" +#include "jit/tls/zend_jit_tls.h" #if defined(IR_TARGET_X86) # define IR_REG_SP 4 /* IR_REG_RSP */ @@ -171,15 +172,9 @@ static uint32_t default_mflags = 0; static bool delayed_call_chain = 0; // TODO: remove this var (use jit->delayed_call_level) ??? #ifdef ZTS -# ifdef _WIN32 -extern uint32_t _tls_index; -extern char *_tls_start; -extern char *_tls_end; -# endif - static size_t tsrm_ls_cache_tcb_offset = 0; -static size_t tsrm_tls_index = 0; -static size_t tsrm_tls_offset = 0; +static size_t tsrm_tls_index = -1; +static size_t tsrm_tls_offset = -1; # define EG_TLS_OFFSET(field) \ (executor_globals_offset + offsetof(zend_executor_globals, field)) @@ -334,6 +329,8 @@ static int zend_jit_assign_to_variable(zend_jit_ctx *jit, zend_jit_addr ref_addr, bool check_exception); +static ir_ref jit_CONST_FUNC(zend_jit_ctx *jit, uintptr_t addr, uint16_t flags); + typedef struct _zend_jit_stub { const char *name; int (*stub)(zend_jit_ctx *jit); @@ -463,6 +460,11 @@ static const char* zend_reg_name(int8_t reg) /* IR helpers */ #ifdef ZTS +static void * ZEND_FASTCALL zend_jit_get_tsrm_ls_cache(void) +{ + return _tsrm_ls_cache; +} + static ir_ref jit_TLS(zend_jit_ctx *jit) { ZEND_ASSERT(jit->ctx.control); @@ -482,9 +484,15 @@ static ir_ref jit_TLS(zend_jit_ctx *jit) ref = insn->op1; } } - jit->tls = ir_TLS( - tsrm_ls_cache_tcb_offset ? tsrm_ls_cache_tcb_offset : tsrm_tls_index, - tsrm_ls_cache_tcb_offset ? IR_NULL : tsrm_tls_offset); + + if (tsrm_ls_cache_tcb_offset == 0 && tsrm_tls_index == -1) { + jit->tls = ir_CALL(IR_ADDR, ir_CONST_FC_FUNC(zend_jit_get_tsrm_ls_cache)); + } else { + jit->tls = ir_TLS( + tsrm_ls_cache_tcb_offset ? tsrm_ls_cache_tcb_offset : tsrm_tls_index, + tsrm_ls_cache_tcb_offset ? IR_NULL : tsrm_tls_offset); + } + return jit->tls; } #endif @@ -1918,15 +1926,13 @@ static void zend_jit_vm_leave(zend_jit_ctx *jit, ir_ref to_opline) static int zend_jit_exception_handler_stub(zend_jit_ctx *jit) { - const void *handler; - - if (zend_jit_vm_kind == ZEND_VM_KIND_HYBRID) { - handler = zend_get_opcode_handler_func(EG(exception_op)); + if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID) { + zend_vm_opcode_handler_func_t handler = (zend_vm_opcode_handler_func_t)zend_get_opcode_handler_func(EG(exception_op)); ir_CALL(IR_VOID, ir_CONST_FUNC(handler)); ir_TAILCALL(IR_VOID, ir_LOAD_A(jit_IP(jit))); } else { - handler = EG(exception_op)->handler; + zend_vm_opcode_handler_t handler = EG(exception_op)->handler; if (GCC_GLOBAL_REGS) { ir_TAILCALL(IR_VOID, ir_CONST_FUNC(handler)); @@ -2045,7 +2051,7 @@ static int zend_jit_leave_function_handler_stub(zend_jit_ctx *jit) ir_IF_FALSE(if_top); - if (zend_jit_vm_kind == ZEND_VM_KIND_HYBRID) { + if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID) { ir_CALL_1(IR_VOID, ir_CONST_FC_FUNC(zend_jit_leave_nested_func_helper), call_info); jit_STORE_IP(jit, ir_LOAD_A(jit_EX(opline))); @@ -2058,7 +2064,7 @@ static int zend_jit_leave_function_handler_stub(zend_jit_ctx *jit) ir_IF_TRUE(if_top); - if (zend_jit_vm_kind == ZEND_VM_KIND_HYBRID) { + if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID) { ir_CALL_1(IR_VOID, ir_CONST_FC_FUNC(zend_jit_leave_top_func_helper), call_info); ir_TAILCALL(IR_VOID, ir_LOAD_A(jit_IP(jit))); } else if (GCC_GLOBAL_REGS) { @@ -2242,7 +2248,7 @@ static int zend_jit_leave_throw_stub(zend_jit_ctx *jit) static int zend_jit_hybrid_runtime_jit_stub(zend_jit_ctx *jit) { - if (zend_jit_vm_kind != ZEND_VM_KIND_HYBRID) { + if (ZEND_VM_KIND != ZEND_VM_KIND_HYBRID) { return 0; } @@ -2255,7 +2261,7 @@ static int zend_jit_hybrid_profile_jit_stub(zend_jit_ctx *jit) { ir_ref addr, func, run_time_cache, jit_extension; - if (zend_jit_vm_kind != ZEND_VM_KIND_HYBRID) { + if (ZEND_VM_KIND != ZEND_VM_KIND_HYBRID) { return 0; } @@ -2311,7 +2317,7 @@ static int _zend_jit_hybrid_hot_counter_stub(zend_jit_ctx *jit, uint32_t cost) static int zend_jit_hybrid_func_hot_counter_stub(zend_jit_ctx *jit) { - if (zend_jit_vm_kind != ZEND_VM_KIND_HYBRID || !JIT_G(hot_func)) { + if (ZEND_VM_KIND != ZEND_VM_KIND_HYBRID || !JIT_G(hot_func)) { return 0; } @@ -2321,7 +2327,7 @@ static int zend_jit_hybrid_func_hot_counter_stub(zend_jit_ctx *jit) static int zend_jit_hybrid_loop_hot_counter_stub(zend_jit_ctx *jit) { - if (zend_jit_vm_kind != ZEND_VM_KIND_HYBRID || !JIT_G(hot_loop)) { + if (ZEND_VM_KIND != ZEND_VM_KIND_HYBRID || !JIT_G(hot_loop)) { return 0; } @@ -2383,7 +2389,7 @@ static int _zend_jit_hybrid_trace_counter_stub(zend_jit_ctx *jit, uint32_t cost) static int zend_jit_hybrid_func_trace_counter_stub(zend_jit_ctx *jit) { - if (zend_jit_vm_kind != ZEND_VM_KIND_HYBRID || !JIT_G(hot_func)) { + if (ZEND_VM_KIND != ZEND_VM_KIND_HYBRID || !JIT_G(hot_func)) { return 0; } @@ -2393,7 +2399,7 @@ static int zend_jit_hybrid_func_trace_counter_stub(zend_jit_ctx *jit) static int zend_jit_hybrid_ret_trace_counter_stub(zend_jit_ctx *jit) { - if (zend_jit_vm_kind != ZEND_VM_KIND_HYBRID || !JIT_G(hot_return)) { + if (ZEND_VM_KIND != ZEND_VM_KIND_HYBRID || !JIT_G(hot_return)) { return 0; } @@ -2403,7 +2409,7 @@ static int zend_jit_hybrid_ret_trace_counter_stub(zend_jit_ctx *jit) static int zend_jit_hybrid_loop_trace_counter_stub(zend_jit_ctx *jit) { - if (zend_jit_vm_kind != ZEND_VM_KIND_HYBRID || !JIT_G(hot_loop)) { + if (ZEND_VM_KIND != ZEND_VM_KIND_HYBRID || !JIT_G(hot_loop)) { return 0; } @@ -2413,7 +2419,7 @@ static int zend_jit_hybrid_loop_trace_counter_stub(zend_jit_ctx *jit) static int zend_jit_trace_halt_stub(zend_jit_ctx *jit) { - if (zend_jit_vm_kind == ZEND_VM_KIND_HYBRID) { + if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID) { ir_TAILCALL(IR_VOID, ir_CONST_FC_FUNC(zend_jit_halt_op->handler)); } else if (GCC_GLOBAL_REGS) { jit_STORE_IP(jit, IR_NULL); @@ -2670,7 +2676,7 @@ static void zend_jit_init_ctx(zend_jit_ctx *jit, uint32_t flags) jit->ctx.fixed_regset = (1<ctx.flags |= IR_NO_STACK_COMBINE; - if (zend_jit_vm_kind == ZEND_VM_KIND_CALL) { + if (ZEND_VM_KIND == ZEND_VM_KIND_CALL) { jit->ctx.flags |= IR_FUNCTION; /* Stack must be 16 byte aligned */ /* TODO: select stack size ??? */ @@ -3127,6 +3133,8 @@ static void zend_jit_setup_disasm(void) REGISTER_DATA(EG(symbol_table)); REGISTER_DATA(CG(map_ptr_base)); +#else /* ZTS */ + REGISTER_HELPER(zend_jit_get_tsrm_ls_cache); #endif #endif } @@ -3138,7 +3146,7 @@ static void zend_jit_calc_trace_prologue_size(void) void *entry; size_t size; - zend_jit_init_ctx(jit, (zend_jit_vm_kind == ZEND_VM_KIND_CALL) ? 0 : IR_START_BR_TARGET); + zend_jit_init_ctx(jit, (ZEND_VM_KIND == ZEND_VM_KIND_CALL) ? 0 : IR_START_BR_TARGET); if (!GCC_GLOBAL_REGS) { ir_ref execute_data_ref = ir_PARAM(IR_ADDR, "execute_data", 1); @@ -3293,7 +3301,6 @@ static void zend_jit_setup_unwinder(void) } #endif - static void zend_jit_setup(bool reattached) { #if defined(IR_TARGET_X86) @@ -3312,170 +3319,21 @@ static void zend_jit_setup(bool reattached) } # endif #endif + #ifdef ZTS -#if defined(IR_TARGET_AARCH64) - tsrm_ls_cache_tcb_offset = tsrm_get_ls_cache_tcb_offset(); - -# ifdef __FreeBSD__ - if (tsrm_ls_cache_tcb_offset == 0) { - TLSDescriptor **where; - - __asm__( - "adrp %0, :tlsdesc:_tsrm_ls_cache\n" - "add %0, %0, :tlsdesc_lo12:_tsrm_ls_cache\n" - : "=r" (where)); - /* See https://github.com/ARM-software/abi-aa/blob/2a70c42d62e9c3eb5887fa50b71257f20daca6f9/aaelf64/aaelf64.rst - * section "Relocations for thread-local storage". - * The first entry holds a pointer to the variable's TLS descriptor resolver function and the second entry holds - * a platform-specific offset or pointer. */ - TLSDescriptor *tlsdesc = where[1]; - - tsrm_tls_offset = tlsdesc->offset; - /* Index is offset by 1 on FreeBSD (https://github.com/freebsd/freebsd-src/blob/22ca6db50f4e6bd75a141f57cf953d8de6531a06/lib/libc/gen/tls.c#L88) */ - tsrm_tls_index = (tlsdesc->index + 1) * 8; + zend_result result = zend_jit_resolve_tsrm_ls_cache_offsets( + &tsrm_ls_cache_tcb_offset, + &tsrm_tls_index, + &tsrm_tls_offset + ); + if (result == FAILURE) { + zend_accel_error(ACCEL_LOG_INFO, + "Could not get _tsrm_ls_cache offsets, will fallback to runtime resolution"); } -# elif defined(__MUSL__) - if (tsrm_ls_cache_tcb_offset == 0) { - size_t **where; - - __asm__( - "adrp %0, :tlsdesc:_tsrm_ls_cache\n" - "add %0, %0, :tlsdesc_lo12:_tsrm_ls_cache\n" - : "=r" (where)); - /* See https://github.com/ARM-software/abi-aa/blob/2a70c42d62e9c3eb5887fa50b71257f20daca6f9/aaelf64/aaelf64.rst */ - size_t *tlsdesc = where[1]; - - tsrm_tls_offset = tlsdesc[1]; - tsrm_tls_index = tlsdesc[0] * 8; - } -# else - ZEND_ASSERT(tsrm_ls_cache_tcb_offset != 0); -# endif -# elif defined(_WIN64) - tsrm_tls_index = _tls_index * sizeof(void*); - - /* To find offset of "_tsrm_ls_cache" in TLS segment we perform a linear scan of local TLS memory */ - /* Probably, it might be better solution */ - do { - void ***tls_mem = ((void****)__readgsqword(0x58))[_tls_index]; - void *val = _tsrm_ls_cache; - size_t offset = 0; - size_t size = (char*)&_tls_end - (char*)&_tls_start; - - while (offset < size) { - if (*tls_mem == val) { - tsrm_tls_offset = offset; - break; - } - tls_mem++; - offset += sizeof(void*); - } - if (offset >= size) { - zend_accel_error_noreturn(ACCEL_LOG_FATAL, "Could not enable JIT: offset >= size"); - } - } while(0); -# elif defined(ZEND_WIN32) - tsrm_tls_index = _tls_index * sizeof(void*); - - /* To find offset of "_tsrm_ls_cache" in TLS segment we perform a linear scan of local TLS memory */ - /* Probably, it might be better solution */ - do { - void ***tls_mem = ((void****)__readfsdword(0x2c))[_tls_index]; - void *val = _tsrm_ls_cache; - size_t offset = 0; - size_t size = (char*)&_tls_end - (char*)&_tls_start; - - while (offset < size) { - if (*tls_mem == val) { - tsrm_tls_offset = offset; - break; - } - tls_mem++; - offset += sizeof(void*); - } - if (offset >= size) { - zend_accel_error_noreturn(ACCEL_LOG_FATAL, "Could not enable JIT: offset >= size"); - } - } while(0); -# elif defined(__APPLE__) && defined(__x86_64__) - tsrm_ls_cache_tcb_offset = tsrm_get_ls_cache_tcb_offset(); - if (tsrm_ls_cache_tcb_offset == 0) { - size_t *ti; - __asm__( - "leaq __tsrm_ls_cache(%%rip),%0" - : "=r" (ti)); - tsrm_tls_offset = ti[2]; - tsrm_tls_index = ti[1] * 8; - } -# 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(__NetBSD__) && !defined(__OpenBSD__) && !defined(__MUSL__) - size_t ret; - - asm ("movq _tsrm_ls_cache@gottpoff(%%rip),%0" - : "=r" (ret)); - tsrm_ls_cache_tcb_offset = ret; -#elif defined(__MUSL__) - size_t *ti; - - __asm__( - "leaq _tsrm_ls_cache@tlsgd(%%rip), %0\n" - : "=D" (ti)); - tsrm_tls_offset = ti[1]; - tsrm_tls_index = ti[0] * 8; -#elif defined(__FreeBSD__) - size_t *ti; - - __asm__( - "leaq _tsrm_ls_cache@tlsgd(%%rip), %0\n" - : "=D" (ti)); - tsrm_tls_offset = ti[1]; - /* Index is offset by 1 on FreeBSD (https://github.com/freebsd/freebsd-src/blob/bf56e8b9c8639ac4447d223b83cdc128107cc3cd/libexec/rtld-elf/rtld.c#L5260) */ - tsrm_tls_index = (ti[0] + 1) * 8; -#else - size_t *ti; - - __asm__( - "leaq _tsrm_ls_cache@tlsgd(%%rip), %0\n" - : "=D" (ti)); - tsrm_tls_offset = ti[1]; - tsrm_tls_index = ti[0] * 16; -#endif - } -# 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(__NetBSD__) && !defined(__OpenBSD__) && !defined(__MUSL__) - size_t ret; - - asm ("leal _tsrm_ls_cache@ntpoff,%0\n" - : "=a" (ret)); - tsrm_ls_cache_tcb_offset = ret; -#else - size_t *ti, _ebx, _ecx, _edx; - - __asm__( - "call 1f\n" - ".subsection 1\n" - "1:\tmovl (%%esp), %%ebx\n\t" - "ret\n" - ".previous\n\t" - "addl $_GLOBAL_OFFSET_TABLE_, %%ebx\n\t" - "leal _tsrm_ls_cache@tlsldm(%%ebx), %0\n\t" - "call ___tls_get_addr@plt\n\t" - "leal _tsrm_ls_cache@tlsldm(%%ebx), %0\n" - : "=a" (ti), "=&b" (_ebx), "=&c" (_ecx), "=&d" (_edx)); - tsrm_tls_offset = ti[1]; - tsrm_tls_index = ti[0] * 8; -#endif - } -# endif #endif #if !defined(ZEND_WIN32) && !defined(IR_TARGET_AARCH64) - if (zend_jit_vm_kind == ZEND_VM_KIND_HYBRID) { + if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID) { zend_jit_set_sp_adj_vm(); // set zend_jit_hybrid_vm_sp_adj } #endif @@ -4176,17 +4034,12 @@ static ir_ref zend_jit_continue_entry(zend_jit_ctx *jit, ir_ref src, unsigned in static int zend_jit_handler(zend_jit_ctx *jit, const zend_op *opline, int may_throw) { - const void *handler; - zend_jit_set_ip(jit, opline); - if (zend_jit_vm_kind == ZEND_VM_KIND_HYBRID) { - handler = zend_get_opcode_handler_func(opline); - } else { - handler = opline->handler; - } if (GCC_GLOBAL_REGS) { + zend_vm_opcode_handler_func_t handler = (zend_vm_opcode_handler_func_t)zend_get_opcode_handler_func(opline); ir_CALL(IR_VOID, ir_CONST_FUNC(handler)); } else { + zend_vm_opcode_handler_t handler = opline->handler; ir_ref ip = ir_CALL_2(IR_ADDR, ir_CONST_FC_FUNC(handler), jit_FP(jit), jit_IP(jit)); jit_STORE_IP(jit, ip); } @@ -4216,28 +4069,27 @@ static int zend_jit_handler(zend_jit_ctx *jit, const zend_op *opline, int may_th static int zend_jit_tail_handler(zend_jit_ctx *jit, const zend_op *opline) { - const void *handler; ir_ref ref; zend_basic_block *bb; zend_jit_set_ip(jit, opline); - if (zend_jit_vm_kind == ZEND_VM_KIND_HYBRID) { + if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID) { if (opline->opcode == ZEND_DO_UCALL || opline->opcode == ZEND_DO_FCALL_BY_NAME || opline->opcode == ZEND_DO_FCALL || opline->opcode == ZEND_RETURN) { /* Use inlined HYBRID VM handler */ - handler = opline->handler; + zend_vm_opcode_handler_t handler = opline->handler; ir_TAILCALL(IR_VOID, ir_CONST_FUNC(handler)); } else { - handler = zend_get_opcode_handler_func(opline); + zend_vm_opcode_handler_func_t handler = (zend_vm_opcode_handler_func_t)zend_get_opcode_handler_func(opline); ir_CALL(IR_VOID, ir_CONST_FUNC(handler)); ref = ir_LOAD_A(jit_IP(jit)); ir_TAILCALL(IR_VOID, ref); } } else { - handler = opline->handler; + zend_vm_opcode_handler_t handler = opline->handler; if (GCC_GLOBAL_REGS) { ir_TAILCALL(IR_VOID, ir_CONST_FUNC(handler)); } else if ((jit->ssa->cfg.flags & ZEND_FUNC_RECURSIVE_DIRECTLY) @@ -4325,6 +4177,11 @@ static int zend_jit_spill_store_inv(zend_jit_ctx *jit, zend_jit_addr src, zend_j ZEND_ASSERT(Z_MODE(src) == IS_REG); ZEND_ASSERT(Z_MODE(dst) == IS_MEM_ZVAL); + if (Z_LOAD(src) || Z_STORE(src)) { + /* it's not necessary to store register if it was previously loaded or already stored */ + return 1; + } + if ((info & MAY_BE_ANY) == MAY_BE_LONG) { jit_set_Z_LVAL(jit, dst, zend_jit_use_reg(jit, src)); if (Z_REG(dst) != ZREG_FP || !JIT_G(current_frame)) { @@ -11132,7 +10989,7 @@ static int zend_jit_leave_func(zend_jit_ctx *jit, if (may_be_top_frame) { // TODO: try to avoid this check ??? - if (zend_jit_vm_kind == ZEND_VM_KIND_HYBRID) { + if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID) { #if 0 /* this check should be handled by the following OPLINE guard */ | cmp IP, zend_jit_halt_op @@ -14806,6 +14663,13 @@ static int zend_jit_assign_obj(zend_jit_ctx *jit, ir_ref slow_inputs = IR_UNUSED; uint32_t res_info = RES_INFO(); + if (Z_MODE(val_addr) == IS_REG + && Z_LOAD(val_addr) + && jit->ra[Z_SSA_VAR(val_addr)].ref == IR_NULL) { + /* Force load */ + zend_jit_use_reg(jit, val_addr); + } + if (val_addr != val_def_addr && val_def_addr) { if (!zend_jit_update_regs(jit, (opline+1)->op1.var, val_addr, val_def_addr, val_info)) { return 0; @@ -16714,7 +16578,7 @@ static int zend_jit_start(zend_jit_ctx *jit, const zend_op_array *op_array, zend int i, count; zend_basic_block *bb; - zend_jit_init_ctx(jit, (zend_jit_vm_kind == ZEND_VM_KIND_CALL) ? 0 : (IR_START_BR_TARGET|IR_ENTRY_BR_TARGET)); + zend_jit_init_ctx(jit, (ZEND_VM_KIND == ZEND_VM_KIND_CALL) ? 0 : (IR_START_BR_TARGET|IR_ENTRY_BR_TARGET)); jit->ctx.spill_base = ZREG_FP; @@ -16741,7 +16605,7 @@ static int zend_jit_start(zend_jit_ctx *jit, const zend_op_array *op_array, zend return 1; } -static void *zend_jit_finish(zend_jit_ctx *jit) +static zend_vm_opcode_handler_t zend_jit_finish(zend_jit_ctx *jit) { void *entry; size_t size; @@ -16792,7 +16656,7 @@ static void *zend_jit_finish(zend_jit_ctx *jit) // ir_mem_unprotect(entry, size); if (!(jit->ctx.flags & IR_FUNCTION) - && zend_jit_vm_kind == ZEND_VM_KIND_HYBRID) { + && ZEND_VM_KIND == ZEND_VM_KIND_HYBRID) { #if !defined(ZEND_WIN32) && !defined(IR_TARGET_AARCH64) sp_offset = zend_jit_hybrid_vm_sp_adj; #else @@ -16825,14 +16689,14 @@ static void *zend_jit_finish(zend_jit_ctx *jit) opline++; } } - opline->handler = entry; + opline->handler = (zend_vm_opcode_handler_t)entry; if (jit->ctx.entries_count) { /* For all entries */ int i = jit->ctx.entries_count; do { ir_insn *insn = &jit->ctx.ir_base[jit->ctx.entries[--i]]; - op_array->opcodes[insn->op2].handler = (char*)entry + insn->op3; + op_array->opcodes[insn->op2].handler = (zend_vm_opcode_handler_t)((char*)entry + insn->op3); } while (i != 0); } } else { @@ -16859,7 +16723,7 @@ static void *zend_jit_finish(zend_jit_ctx *jit) zend_string_release(str); } - return entry; + return (zend_vm_opcode_handler_t)entry; } static const void *zend_jit_trace_allocate_exit_group(uint32_t n) @@ -17160,7 +17024,7 @@ static int zend_jit_trace_handler(zend_jit_ctx *jit, const zend_op_array *op_arr opline->opcode == ZEND_RETURN_BY_REF || opline->opcode == ZEND_GENERATOR_CREATE) { - if (zend_jit_vm_kind == ZEND_VM_KIND_HYBRID) { + if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID) { if (trace->op != ZEND_JIT_TRACE_END || (trace->stop != ZEND_JIT_TRACE_STOP_RETURN && trace->stop < ZEND_JIT_TRACE_STOP_INTERPRETER)) { @@ -17274,7 +17138,7 @@ static int zend_jit_deoptimizer_start(zend_jit_ctx *jit, uint32_t trace_num, uint32_t exit_num) { - zend_jit_init_ctx(jit, (zend_jit_vm_kind == ZEND_VM_KIND_CALL) ? 0 : IR_START_BR_TARGET); + zend_jit_init_ctx(jit, (ZEND_VM_KIND == ZEND_VM_KIND_CALL) ? 0 : IR_START_BR_TARGET); jit->ctx.spill_base = ZREG_FP; @@ -17295,7 +17159,7 @@ static int zend_jit_trace_start(zend_jit_ctx *jit, zend_jit_trace_info *parent, uint32_t exit_num) { - zend_jit_init_ctx(jit, (zend_jit_vm_kind == ZEND_VM_KIND_CALL) ? 0 : IR_START_BR_TARGET); + zend_jit_init_ctx(jit, (ZEND_VM_KIND == ZEND_VM_KIND_CALL) ? 0 : IR_START_BR_TARGET); jit->ctx.spill_base = ZREG_FP; diff --git a/ext/opcache/jit/zend_jit_trace.c b/ext/opcache/jit/zend_jit_trace.c index aeec674d60f..4965193f786 100644 --- a/ext/opcache/jit/zend_jit_trace.c +++ b/ext/opcache/jit/zend_jit_trace.c @@ -3409,7 +3409,7 @@ static void zend_jit_trace_setup_ret_counter(const zend_op *opline, size_t offse ZEND_JIT_COUNTER_NUM = (ZEND_JIT_COUNTER_NUM + 1) % ZEND_HOT_COUNTERS_COUNT; } ZEND_OP_TRACE_INFO(next_opline, offset)->trace_flags = ZEND_JIT_TRACE_START_RETURN; - next_opline->handler = (const void*)zend_jit_ret_trace_counter_handler; + next_opline->handler = zend_jit_ret_trace_counter_handler; } } @@ -4079,9 +4079,9 @@ static bool zend_jit_trace_may_throw(const zend_op *opline, return zend_may_throw_ex(opline, ssa_op, op_array, ssa, t1, t2); } -static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t parent_trace, uint32_t exit_num) +static zend_vm_opcode_handler_t zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t parent_trace, uint32_t exit_num) { - const void *handler = NULL; + zend_vm_opcode_handler_t handler = NULL; zend_jit_ctx ctx; zend_jit_ctx *jit = &ctx; zend_jit_reg_var *ra = NULL; @@ -7392,9 +7392,9 @@ static zend_string *zend_jit_trace_escape_name(uint32_t trace_num, uint32_t exit return buf.s; } -static const void *zend_jit_trace_exit_to_vm(uint32_t trace_num, uint32_t exit_num) +static zend_vm_opcode_handler_t zend_jit_trace_exit_to_vm(uint32_t trace_num, uint32_t exit_num) { - const void *handler = NULL; + zend_vm_opcode_handler_t handler = NULL; zend_jit_ctx ctx; zend_string *name; void *checkpoint; @@ -7458,7 +7458,7 @@ jit_failure: static zend_jit_trace_stop zend_jit_compile_root_trace(zend_jit_trace_rec *trace_buffer, const zend_op *opline, size_t offset) { zend_jit_trace_stop ret; - const void *handler; + zend_vm_opcode_handler_t handler; uint8_t orig_trigger; zend_jit_trace_info *t = NULL; zend_jit_trace_exit_info exit_info[ZEND_JIT_TRACE_MAX_EXITS]; @@ -8832,11 +8832,11 @@ int ZEND_FASTCALL zend_jit_trace_exit(uint32_t exit_num, zend_jit_registers_buf zend_jit_unprotect(); if (ZEND_OP_TRACE_INFO(t->opline, jit_extension->offset)->trace_flags & ZEND_JIT_TRACE_START_LOOP) { - ((zend_op*)(t->opline))->handler = (const void*)zend_jit_loop_trace_counter_handler; + ((zend_op*)(t->opline))->handler = zend_jit_loop_trace_counter_handler; } else if (ZEND_OP_TRACE_INFO(t->opline, jit_extension->offset)->trace_flags & ZEND_JIT_TRACE_START_ENTER) { - ((zend_op*)(t->opline))->handler = (const void*)zend_jit_func_trace_counter_handler; + ((zend_op*)(t->opline))->handler = zend_jit_func_trace_counter_handler; } else if (ZEND_OP_TRACE_INFO(t->opline, jit_extension->offset)->trace_flags & ZEND_JIT_TRACE_START_RETURN) { - ((zend_op*)(t->opline))->handler = (const void*)zend_jit_ret_trace_counter_handler; + ((zend_op*)(t->opline))->handler = zend_jit_ret_trace_counter_handler; } ZEND_OP_TRACE_INFO(t->opline, jit_extension->offset)->trace_flags &= ZEND_JIT_TRACE_START_LOOP|ZEND_JIT_TRACE_START_ENTER|ZEND_JIT_TRACE_START_RETURN; @@ -8889,9 +8889,9 @@ static int zend_jit_restart_hot_trace_counters(zend_op_array *op_array) jit_extension->trace_info[i].trace_flags &= ZEND_JIT_TRACE_START_LOOP | ZEND_JIT_TRACE_START_ENTER | ZEND_JIT_TRACE_UNSUPPORTED; if (jit_extension->trace_info[i].trace_flags == ZEND_JIT_TRACE_START_LOOP) { - op_array->opcodes[i].handler = (const void*)zend_jit_loop_trace_counter_handler; + op_array->opcodes[i].handler = zend_jit_loop_trace_counter_handler; } else if (jit_extension->trace_info[i].trace_flags == ZEND_JIT_TRACE_START_ENTER) { - op_array->opcodes[i].handler = (const void*)zend_jit_func_trace_counter_handler; + op_array->opcodes[i].handler = zend_jit_func_trace_counter_handler; } else { op_array->opcodes[i].handler = jit_extension->trace_info[i].orig_handler; } @@ -8917,7 +8917,7 @@ static int zend_jit_setup_hot_trace_counters(zend_op_array *op_array) jit_extension->offset = (char*)jit_extension->trace_info - (char*)op_array->opcodes; for (i = 0; i < op_array->last; i++) { jit_extension->trace_info[i].orig_handler = op_array->opcodes[i].handler; - jit_extension->trace_info[i].call_handler = zend_get_opcode_handler_func(&op_array->opcodes[i]); + jit_extension->trace_info[i].call_handler = (zend_vm_opcode_handler_func_t)zend_get_opcode_handler_func(&op_array->opcodes[i]); jit_extension->trace_info[i].counter = NULL; jit_extension->trace_info[i].trace_flags = zend_jit_trace_supported(&op_array->opcodes[i]); @@ -8939,7 +8939,7 @@ static int zend_jit_setup_hot_trace_counters(zend_op_array *op_array) /* loop header */ opline = op_array->opcodes + cfg.blocks[i].start; if (!(ZEND_OP_TRACE_INFO(opline, jit_extension->offset)->trace_flags & ZEND_JIT_TRACE_UNSUPPORTED)) { - opline->handler = (const void*)zend_jit_loop_trace_counter_handler; + opline->handler = zend_jit_loop_trace_counter_handler; if (!ZEND_OP_TRACE_INFO(opline, jit_extension->offset)->counter) { ZEND_OP_TRACE_INFO(opline, jit_extension->offset)->counter = &zend_jit_hot_counters[ZEND_JIT_COUNTER_NUM]; @@ -8964,7 +8964,7 @@ static int zend_jit_setup_hot_trace_counters(zend_op_array *op_array) if (!ZEND_OP_TRACE_INFO(opline, jit_extension->offset)->trace_flags) { /* function entry */ - opline->handler = (const void*)zend_jit_func_trace_counter_handler; + opline->handler = zend_jit_func_trace_counter_handler; ZEND_OP_TRACE_INFO(opline, jit_extension->offset)->counter = &zend_jit_hot_counters[ZEND_JIT_COUNTER_NUM]; ZEND_JIT_COUNTER_NUM = (ZEND_JIT_COUNTER_NUM + 1) % ZEND_HOT_COUNTERS_COUNT; diff --git a/ext/opcache/jit/zend_jit_vm_helpers.c b/ext/opcache/jit/zend_jit_vm_helpers.c index 4348fbd53ad..b19de612c44 100644 --- a/ext/opcache/jit/zend_jit_vm_helpers.c +++ b/ext/opcache/jit/zend_jit_vm_helpers.c @@ -298,6 +298,7 @@ void ZEND_FASTCALL zend_jit_undefined_string_key(EXECUTE_DATA_D) ZVAL_NULL(result); } +#if ZEND_VM_KIND != ZEND_VM_KIND_HYBRID ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_jit_profile_helper(ZEND_OPCODE_HANDLER_ARGS) { zend_op_array *op_array = (zend_op_array*)EX(func); @@ -341,6 +342,7 @@ ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_jit_loop_counter_helper(ZEND_OPCODE_H ZEND_OPCODE_TAIL_CALL(handler); } } +#endif static zend_always_inline zend_constant* _zend_quick_get_constant( const zval *key, uint32_t flags, int check_defined_only) @@ -402,6 +404,7 @@ zend_constant* ZEND_FASTCALL zend_jit_check_constant(const zval *key) return _zend_quick_get_constant(key, 0, 1); } +#if ZEND_VM_KIND != ZEND_VM_KIND_HYBRID static zend_always_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_jit_trace_counter_helper(ZEND_OPCODE_HANDLER_ARGS_EX uint32_t cost) { zend_jit_op_array_trace_extension *jit_extension = @@ -450,6 +453,7 @@ ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_jit_loop_trace_helper(ZEND_OPCODE_HAN ZEND_OPCODE_TAIL_CALL_EX(zend_jit_trace_counter_helper, ((ZEND_JIT_COUNTER_INIT + JIT_G(hot_loop) - 1) / JIT_G(hot_loop))); } +#endif #define TRACE_RECORD(_op, _info, _ptr) \ trace_buffer[idx].info = _op | (_info); \ @@ -657,7 +661,7 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex, zend_jit_trace_stop halt = 0; int level = 0; int ret_level = 0; - zend_vm_opcode_handler_t handler; + zend_vm_opcode_handler_func_t handler; const zend_op_array *op_array; zend_jit_op_array_trace_extension *jit_extension; size_t offset; @@ -983,7 +987,7 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex, break; } - handler = (zend_vm_opcode_handler_t)ZEND_OP_TRACE_INFO(opline, offset)->call_handler; + handler = ZEND_OP_TRACE_INFO(opline, offset)->call_handler; #ifdef HAVE_GCC_GLOBAL_REGS handler(); if (UNEXPECTED(opline == zend_jit_halt_op)) { diff --git a/ext/opcache/opcache.stub.php b/ext/opcache/opcache.stub.php index 526da238219..32673bb1dce 100644 --- a/ext/opcache/opcache.stub.php +++ b/ext/opcache/opcache.stub.php @@ -23,3 +23,5 @@ function opcache_jit_blacklist(Closure $closure): void {} function opcache_get_configuration(): array|false {} function opcache_is_script_cached(string $filename): bool {} + +function opcache_is_script_cached_in_file_cache(string $filename): bool {} diff --git a/ext/opcache/opcache_arginfo.h b/ext/opcache/opcache_arginfo.h index b4dc1f33a5f..7fff6b1eb0d 100644 --- a/ext/opcache/opcache_arginfo.h +++ b/ext/opcache/opcache_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: c416c231c5d1270b7e5961f84cc3ca3e29db4959 */ + * Stub hash: a8de025fa96a78db3a26d53a18bb2b365d094eca */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_opcache_reset, 0, 0, _IS_BOOL, 0) ZEND_END_ARG_INFO() @@ -26,6 +26,8 @@ ZEND_END_ARG_INFO() #define arginfo_opcache_is_script_cached arginfo_opcache_compile_file +#define arginfo_opcache_is_script_cached_in_file_cache arginfo_opcache_compile_file + ZEND_FUNCTION(opcache_reset); ZEND_FUNCTION(opcache_get_status); ZEND_FUNCTION(opcache_compile_file); @@ -33,6 +35,7 @@ ZEND_FUNCTION(opcache_invalidate); ZEND_FUNCTION(opcache_jit_blacklist); ZEND_FUNCTION(opcache_get_configuration); ZEND_FUNCTION(opcache_is_script_cached); +ZEND_FUNCTION(opcache_is_script_cached_in_file_cache); static const zend_function_entry ext_functions[] = { ZEND_FE(opcache_reset, arginfo_opcache_reset) @@ -42,5 +45,6 @@ static const zend_function_entry ext_functions[] = { ZEND_FE(opcache_jit_blacklist, arginfo_opcache_jit_blacklist) ZEND_FE(opcache_get_configuration, arginfo_opcache_get_configuration) ZEND_FE(opcache_is_script_cached, arginfo_opcache_is_script_cached) + ZEND_FE(opcache_is_script_cached_in_file_cache, arginfo_opcache_is_script_cached_in_file_cache) ZEND_FE_END }; diff --git a/ext/opcache/shared_alloc_mmap.c b/ext/opcache/shared_alloc_mmap.c index 18c7532478f..cf5dbb29ebf 100644 --- a/ext/opcache/shared_alloc_mmap.c +++ b/ext/opcache/shared_alloc_mmap.c @@ -52,7 +52,7 @@ #endif #if defined(HAVE_JIT) && (defined(__linux__) || defined(__FreeBSD__)) && (defined(__x86_64__) || defined (__aarch64__)) && !defined(__SANITIZE_ADDRESS__) -static void *find_prefered_mmap_base(size_t requested_size) +static void *find_preferred_mmap_base(size_t requested_size) { size_t huge_page_size = 2 * 1024 * 1024; uintptr_t last_free_addr = huge_page_size; @@ -204,7 +204,7 @@ static int create_segments(size_t requested_size, zend_shared_segment ***shared_ void *hint; if (JIT_G(enabled) && JIT_G(buffer_size) && zend_jit_check_support() == SUCCESS) { - hint = find_prefered_mmap_base(requested_size); + hint = find_preferred_mmap_base(requested_size); } else { /* Do not use a hint if JIT is not enabled, as this profits only JIT and * this is potentially unsafe when the only suitable candidate is just diff --git a/ext/opcache/tests/api/opcache_preloading.inc b/ext/opcache/tests/api/opcache_preloading.inc new file mode 100644 index 00000000000..0466028a370 --- /dev/null +++ b/ext/opcache/tests/api/opcache_preloading.inc @@ -0,0 +1,3 @@ + diff --git a/ext/opcache/tests/api/opcache_preloading_001.phpt b/ext/opcache/tests/api/opcache_preloading_001.phpt new file mode 100644 index 00000000000..e30cbbd7d15 --- /dev/null +++ b/ext/opcache/tests/api/opcache_preloading_001.phpt @@ -0,0 +1,21 @@ +--TEST-- +opcache_preloading() api 001 +--EXTENSIONS-- +zend_test +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.preload={PWD}/opcache_preloading.inc +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +%sopcache_preloading.inc: 1 +%sopcache_preloading_001.php: 0 diff --git a/ext/opcache/tests/api/opcache_preloading_002.phpt b/ext/opcache/tests/api/opcache_preloading_002.phpt new file mode 100644 index 00000000000..30bf5a5bc03 --- /dev/null +++ b/ext/opcache/tests/api/opcache_preloading_002.phpt @@ -0,0 +1,24 @@ +--TEST-- +opcache_preloading() api 002 +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.preload={PWD}/opcache_preloading.inc +opcache.preload_user={ENV:TEST_NON_ROOT_USER} +--EXTENSIONS-- +posix +zend_test +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +%sopcache_preloading.inc: 1 +%sopcache_preloading_002.php: 0 diff --git a/ext/opcache/tests/gh16979_check_file_cache_function.inc b/ext/opcache/tests/gh16979_check_file_cache_function.inc new file mode 100644 index 00000000000..6e4c482985f --- /dev/null +++ b/ext/opcache/tests/gh16979_check_file_cache_function.inc @@ -0,0 +1,3 @@ + +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.jit=disable +opcache.file_cache="{PWD}/gh16979_cache" +opcache.file_update_protection=0 +--EXTENSIONS-- +opcache +--FILE-- + +--CLEAN-- +isDir()) { + @rmdir($fileinfo->getRealPath()); + } else { + @unlink($fileinfo->getRealPath()); + } + } + @rmdir($dir); +} +removeDirRecursive(__DIR__ . '/gh16979_cache'); +?> +--EXPECT-- +bool(false) +bool(true) +bool(false) diff --git a/ext/opcache/tests/gh17422/001.phpt b/ext/opcache/tests/gh17422/001.phpt new file mode 100644 index 00000000000..04a8bc38a9e --- /dev/null +++ b/ext/opcache/tests/gh17422/001.phpt @@ -0,0 +1,17 @@ +--TEST-- +GH-17422 (OPcache bypasses the user-defined error handler for deprecations) +--FILE-- + +--EXPECT-- +set_error_handler: "continue" targeting switch is equivalent to "break" +OK: warning diff --git a/ext/opcache/tests/gh17422/002.phpt b/ext/opcache/tests/gh17422/002.phpt new file mode 100644 index 00000000000..6145f71a8e5 --- /dev/null +++ b/ext/opcache/tests/gh17422/002.phpt @@ -0,0 +1,21 @@ +--TEST-- +GH-17422 (OPcache bypasses the user-defined error handler for deprecations) - Throwing error handler +--FILE-- +getMessage(), PHP_EOL; +} + +warning(); + +?> +--EXPECT-- +Caught: "continue" targeting switch is equivalent to "break" +OK: warning diff --git a/ext/opcache/tests/gh17422/003.phpt b/ext/opcache/tests/gh17422/003.phpt new file mode 100644 index 00000000000..a1330eb88af --- /dev/null +++ b/ext/opcache/tests/gh17422/003.phpt @@ -0,0 +1,17 @@ +--TEST-- +GH-17422 (OPcache bypasses the user-defined error handler for deprecations) - Fatal Error +--FILE-- + +--EXPECTF-- +Fatal error: Cannot redeclare function fatal_error() (previously declared in %s:%d) in %s on line %d diff --git a/ext/opcache/tests/gh17422/004.phpt b/ext/opcache/tests/gh17422/004.phpt new file mode 100644 index 00000000000..4fa659a763e --- /dev/null +++ b/ext/opcache/tests/gh17422/004.phpt @@ -0,0 +1,22 @@ +--TEST-- +GH-17422 (OPcache bypasses the user-defined error handler for deprecations) - eval +--FILE-- + +--EXPECTF-- +Fatal error: Cannot redeclare function warning() %s diff --git a/ext/opcache/tests/gh17422/005.phpt b/ext/opcache/tests/gh17422/005.phpt new file mode 100644 index 00000000000..1b4818d91cc --- /dev/null +++ b/ext/opcache/tests/gh17422/005.phpt @@ -0,0 +1,16 @@ +--TEST-- +GH-17422 (OPcache bypasses the user-defined error handler for deprecations) - require +--FILE-- + +--EXPECT-- +OK: dummy diff --git a/ext/opcache/tests/gh17422/006.phpt b/ext/opcache/tests/gh17422/006.phpt new file mode 100644 index 00000000000..3c1303dfa84 --- /dev/null +++ b/ext/opcache/tests/gh17422/006.phpt @@ -0,0 +1,25 @@ +--TEST-- +GH-17422 (OPcache bypasses the user-defined error handler for deprecations) - File cache +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_cache="{TMP}" +opcache.file_cache_only=1 +opcache.record_warnings=1 +--EXTENSIONS-- +opcache +--FILE-- + +--EXPECT-- +set_error_handler: "continue" targeting switch is equivalent to "break" +OK: warning diff --git a/ext/opcache/tests/gh17422/007.phpt b/ext/opcache/tests/gh17422/007.phpt new file mode 100644 index 00000000000..59b2306f52d --- /dev/null +++ b/ext/opcache/tests/gh17422/007.phpt @@ -0,0 +1,18 @@ +--TEST-- +GH-17422 (OPcache bypasses the user-defined error handler for deprecations) - Fatal after warning +--FILE-- + +--EXPECTF-- +Warning: "continue" targeting switch is equivalent to "break" in %s on line %d + +Fatal error: Cannot redeclare function warning() (previously declared in %s:%d) in %s on line %d diff --git a/ext/opcache/tests/gh17422/008.phpt b/ext/opcache/tests/gh17422/008.phpt new file mode 100644 index 00000000000..bcabb071e65 --- /dev/null +++ b/ext/opcache/tests/gh17422/008.phpt @@ -0,0 +1,14 @@ +--TEST-- +GH-17422 (OPcache bypasses the user-defined error handler for deprecations) - Early binding warning +--FILE-- + +--EXPECTF-- +set_error_handler: Return type of C::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/ext/opcache/tests/gh17422/009.phpt b/ext/opcache/tests/gh17422/009.phpt new file mode 100644 index 00000000000..b071ad9478d --- /dev/null +++ b/ext/opcache/tests/gh17422/009.phpt @@ -0,0 +1,16 @@ +--TEST-- +GH-17422 (OPcache bypasses the user-defined error handler for deprecations) - Early binding error after warning +--FILE-- + +--EXPECTF-- +Deprecated: Return type of C::getTimezone() should either be compatible with DateTime::getTimezone(): DateTimeZone|false, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in %s on line %d + +Fatal error: Declaration of C::getTimestamp(C $arg): int must be compatible with DateTime::getTimestamp(): int in %s on line %d diff --git a/ext/opcache/tests/gh17422/010.phpt b/ext/opcache/tests/gh17422/010.phpt new file mode 100644 index 00000000000..4e94b5e7794 --- /dev/null +++ b/ext/opcache/tests/gh17422/010.phpt @@ -0,0 +1,14 @@ +--TEST-- +GH-17422 (OPcache bypasses the user-defined error handler for deprecations) - Inheritance warning +--FILE-- + +--EXPECTF-- +set_error_handler: Return type of C::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/ext/opcache/tests/gh17422/011.phpt b/ext/opcache/tests/gh17422/011.phpt new file mode 100644 index 00000000000..7034e5b2a46 --- /dev/null +++ b/ext/opcache/tests/gh17422/011.phpt @@ -0,0 +1,16 @@ +--TEST-- +GH-17422 (OPcache bypasses the user-defined error handler for deprecations) - Inheritance error after warning +--FILE-- + +--EXPECTF-- +Deprecated: Return type of C::getTimezone() should either be compatible with DateTime::getTimezone(): DateTimeZone|false, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in %s on line %d + +Fatal error: Declaration of C::getTimestamp(C $arg): int must be compatible with DateTime::getTimestamp(): int %s on line %d diff --git a/ext/opcache/tests/gh17422/dummy.inc b/ext/opcache/tests/gh17422/dummy.inc new file mode 100644 index 00000000000..0bb25355612 --- /dev/null +++ b/ext/opcache/tests/gh17422/dummy.inc @@ -0,0 +1,4 @@ +value = $value['value']; + } + return $item; + }, + null, + CacheItem::class); + return $test($value); +} + +$values = [['value'=>'str'], ['value'=>'str'], ['value'=>42]]; +$n = count($values); + +for ($i = 0; $i < $n; $i++) { + test($values[$i]); +} +?> +OK +--EXPECT-- +OK diff --git a/ext/opcache/tests/preload_dynamic_def_removal.inc b/ext/opcache/tests/preload_dynamic_def_removal.inc index 27ec69120ea..2a6a44ef509 100644 --- a/ext/opcache/tests/preload_dynamic_def_removal.inc +++ b/ext/opcache/tests/preload_dynamic_def_removal.inc @@ -5,6 +5,15 @@ class Test { echo "dynamic\n"; } } + + public int $hook { + get { + function dynamic_in_hook() { + echo "dynamic in hook\n"; + } + return 1; + } + } } function func() { @@ -16,3 +25,4 @@ function func() { $test = new Test; $test->method(); func(); +$test->hook; diff --git a/ext/opcache/tests/preload_dynamic_def_removal.phpt b/ext/opcache/tests/preload_dynamic_def_removal.phpt index d4f2bb070cc..acc26873e18 100644 --- a/ext/opcache/tests/preload_dynamic_def_removal.phpt +++ b/ext/opcache/tests/preload_dynamic_def_removal.phpt @@ -15,7 +15,9 @@ if (PHP_OS_FAMILY == 'Windows') die('skip Preloading is not supported on Windows --EXPECT-- dynamic dynamic2 +dynamic in hook diff --git a/ext/opcache/tests/revalidate_path_01.phpt b/ext/opcache/tests/revalidate_path_01.phpt index ff87e73b554..c8cd1ea493a 100644 --- a/ext/opcache/tests/revalidate_path_01.phpt +++ b/ext/opcache/tests/revalidate_path_01.phpt @@ -30,7 +30,7 @@ if (substr(PHP_OS, 0, 3) == 'WIN') { @rmdir($link); $ln = str_replace('/', '\\', $link); $d1 = realpath($dir1); - `mklink /j $ln $d1`; + shell_exec("mklink /j $ln $d1"); } else { @unlink($link); @symlink($dir1, $link); @@ -45,7 +45,7 @@ if (substr(PHP_OS, 0, 3) == 'WIN') { @rmdir($link); $ln = str_replace('/', '\\', $link); $d2 = realpath($dir2); - `mklink /j $ln $d2`; + shell_exec("mklink /j $ln $d2"); } else { @unlink($link); @symlink($dir2, $link); diff --git a/ext/opcache/tests/zzz_basic_logging.phpt b/ext/opcache/tests/zzz_basic_logging.phpt index a53c6a8db9d..88290f6a169 100644 --- a/ext/opcache/tests/zzz_basic_logging.phpt +++ b/ext/opcache/tests/zzz_basic_logging.phpt @@ -13,12 +13,14 @@ opcache.log_verbosity_level=4 opcache.huge_code_pages=0 opcache.preload= opcache.interned_strings_buffer=8 +opcache.blacklist_filename= --EXTENSIONS-- opcache --SKIPIF-- --FILE-- | - | Xinchen Hui | - +----------------------------------------------------------------------+ - */ +*/ -/* Header moved to Zend. This file is retained for BC. */ -#include "zend_smart_string.h" +#include "zend_accelerator_api.h" +#include "ZendAccelerator.h" + +ZEND_API bool opcache_preloading(void) +{ + return ZCG(preloading); +} diff --git a/ext/opcache/zend_accelerator_api.h b/ext/opcache/zend_accelerator_api.h new file mode 100644 index 00000000000..4ea42f29d17 --- /dev/null +++ b/ext/opcache/zend_accelerator_api.h @@ -0,0 +1,29 @@ +/* + +----------------------------------------------------------------------+ + | Zend OPcache | + +----------------------------------------------------------------------+ + | Copyright (c) The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | https://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ +*/ + +#ifndef ZEND_ACCELERATOR_API_H +#define ZEND_ACCELERATOR_API_H + +#include "Zend/zend_portability.h" + +BEGIN_EXTERN_C() + +/* Returns true during preloading */ +ZEND_API bool opcache_preloading(void); + +END_EXTERN_C() + +#endif /* ZEND_ACCELERATOR_API_H */ diff --git a/ext/opcache/zend_accelerator_module.c b/ext/opcache/zend_accelerator_module.c index a4f632872f5..9a168b38baa 100644 --- a/ext/opcache/zend_accelerator_module.c +++ b/ext/opcache/zend_accelerator_module.c @@ -25,8 +25,11 @@ #include "ZendAccelerator.h" #include "zend_API.h" #include "zend_closures.h" +#include "zend_extensions.h" +#include "zend_modules.h" #include "zend_shared_alloc.h" #include "zend_accelerator_blacklist.h" +#include "zend_file_cache.h" #include "php_ini.h" #include "SAPI.h" #include "zend_virtual_cwd.h" @@ -76,6 +79,15 @@ static int validate_api_restriction(void) static ZEND_INI_MH(OnUpdateMemoryConsumption) { + if (accel_startup_ok) { + if (strcmp(sapi_module.name, "fpm-fcgi") == 0) { + zend_accel_error(ACCEL_LOG_WARNING, "opcache.memory_consumption cannot be changed when OPcache is already set up. Are you using php_admin_value[opcache.memory_consumption] in an individual pool's configuration?\n"); + } else { + zend_accel_error(ACCEL_LOG_WARNING, "opcache.memory_consumption cannot be changed when OPcache is already set up.\n"); + } + return FAILURE; + } + zend_long *p = (zend_long *) ZEND_INI_GET_ADDR(); zend_long memsize = atoi(ZSTR_VAL(new_value)); /* sanity check we must use at least 8 MB */ @@ -364,6 +376,23 @@ static int filename_is_in_cache(zend_string *filename) return 0; } +static int filename_is_in_file_cache(zend_string *filename) +{ + zend_string *realpath = zend_resolve_path(filename); + if (!realpath) { + return 0; + } + + zend_file_handle handle; + zend_stream_init_filename_ex(&handle, filename); + handle.opened_path = realpath; + + zend_persistent_script *result = zend_file_cache_script_load_ex(&handle, true); + zend_destroy_file_handle(&handle); + + return result != NULL; +} + static int accel_file_in_cache(INTERNAL_FUNCTION_PARAMETERS) { if (ZEND_NUM_ARGS() == 1) { @@ -405,13 +434,19 @@ static ZEND_NAMED_FUNCTION(accel_is_readable) static ZEND_MINIT_FUNCTION(zend_accelerator) { - (void)type; /* keep the compiler happy */ - - REGISTER_INI_ENTRIES(); + start_accel_extension(); return SUCCESS; } +void zend_accel_register_ini_entries(void) +{ + zend_module_entry *module = zend_hash_str_find_ptr_lc(&module_registry, + ACCELERATOR_PRODUCT_NAME, strlen(ACCELERATOR_PRODUCT_NAME)); + + zend_register_ini_entries_ex(ini_entries, module->module_number, module->type); +} + void zend_accel_override_file_functions(void) { zend_function *old_function; @@ -442,6 +477,7 @@ static ZEND_MSHUTDOWN_FUNCTION(zend_accelerator) UNREGISTER_INI_ENTRIES(); accel_shutdown(); + return SUCCESS; } @@ -554,7 +590,7 @@ void zend_accel_info(ZEND_MODULE_INFO_FUNC_ARGS) DISPLAY_INI_ENTRIES(); } -static zend_module_entry accel_module_entry = { +zend_module_entry opcache_module_entry = { STANDARD_MODULE_HEADER, ACCELERATOR_PRODUCT_NAME, ext_functions, @@ -569,11 +605,6 @@ static zend_module_entry accel_module_entry = { STANDARD_MODULE_PROPERTIES_EX }; -int start_accel_module(void) -{ - return zend_startup_module(&accel_module_entry); -} - /* {{{ Get the scripts which are accelerated by ZendAccelerator */ static int accelerator_get_scripts(zval *return_value) { @@ -581,8 +612,6 @@ static int accelerator_get_scripts(zval *return_value) zval persistent_script_report; zend_accel_hash_entry *cache_entry; struct tm *ta; - struct timeval exec_time; - struct timeval fetch_time; if (!ZCG(accelerator_enabled) || accelerator_shm_read_lock() != SUCCESS) { return 0; @@ -612,8 +641,6 @@ static int accelerator_get_scripts(zval *return_value) if (ZCG(accel_directives).validate_timestamps) { add_assoc_long(&persistent_script_report, "timestamp", (zend_long)script->timestamp); } - timerclear(&exec_time); - timerclear(&fetch_time); add_assoc_long(&persistent_script_report, "revalidate", (zend_long)script->dynamic_members.revalidate); @@ -999,3 +1026,27 @@ ZEND_FUNCTION(opcache_is_script_cached) RETURN_BOOL(filename_is_in_cache(script_name)); } + +/* {{{ Return true if the script is cached in OPCache file cache, false if it is not cached or if OPCache is not running. */ +ZEND_FUNCTION(opcache_is_script_cached_in_file_cache) +{ + zend_string *script_name; + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_STR(script_name) + ZEND_PARSE_PARAMETERS_END(); + + if (!validate_api_restriction()) { + RETURN_FALSE; + } + + if (!(ZCG(accelerator_enabled) || ZCG(accel_directives).file_cache_only)) { + RETURN_FALSE; + } + + if (!ZCG(accel_directives).file_cache) { + RETURN_FALSE; + } + + RETURN_BOOL(filename_is_in_file_cache(script_name)); +} diff --git a/ext/opcache/zend_accelerator_module.h b/ext/opcache/zend_accelerator_module.h index 656336eeba7..6eff0624bbb 100644 --- a/ext/opcache/zend_accelerator_module.h +++ b/ext/opcache/zend_accelerator_module.h @@ -22,7 +22,12 @@ #ifndef ZEND_ACCELERATOR_MODULE_H #define ZEND_ACCELERATOR_MODULE_H -int start_accel_module(void); +#include "Zend/zend_modules.h" + +#define phpext_opcache_ptr &opcache_module_entry +extern zend_module_entry opcache_module_entry; + +void zend_accel_register_ini_entries(void); void zend_accel_override_file_functions(void); diff --git a/ext/opcache/zend_file_cache.c b/ext/opcache/zend_file_cache.c index fee90e42b57..4b47bb54e7a 100644 --- a/ext/opcache/zend_file_cache.c +++ b/ext/opcache/zend_file_cache.c @@ -1871,7 +1871,14 @@ static void zend_file_cache_unserialize(zend_persistent_script *script, zend_file_cache_unserialize_early_bindings(script, buf); } +static zend_persistent_script file_cache_validate_success_script; + zend_persistent_script *zend_file_cache_script_load(zend_file_handle *file_handle) +{ + return zend_file_cache_script_load_ex(file_handle, false); +} + +zend_persistent_script *zend_file_cache_script_load_ex(zend_file_handle *file_handle, bool validate_only) { zend_string *full_path = file_handle->opened_path; int fd; @@ -1948,6 +1955,16 @@ zend_persistent_script *zend_file_cache_script_load(zend_file_handle *file_handl return NULL; } + /* return here if validating */ + if (validate_only) { + if (zend_file_cache_flock(fd, LOCK_UN) != 0) { + zend_accel_error(ACCEL_LOG_WARNING, "opcache cannot unlock file '%s'\n", filename); + } + close(fd); + efree(filename); + return &file_cache_validate_success_script; + } + checkpoint = zend_arena_checkpoint(CG(arena)); #if defined(__AVX__) || defined(__SSE2__) /* Align to 64-byte boundary */ diff --git a/ext/opcache/zend_file_cache.h b/ext/opcache/zend_file_cache.h index 8f067f5f37a..452f6b2c4c2 100644 --- a/ext/opcache/zend_file_cache.h +++ b/ext/opcache/zend_file_cache.h @@ -21,6 +21,7 @@ int zend_file_cache_script_store(zend_persistent_script *script, bool in_shm); zend_persistent_script *zend_file_cache_script_load(zend_file_handle *file_handle); +zend_persistent_script *zend_file_cache_script_load_ex(zend_file_handle *file_handle, bool validate_only); void zend_file_cache_invalidate(zend_string *full_path); #endif /* ZEND_FILE_CACHE_H */ diff --git a/ext/opcache/zend_persist.c b/ext/opcache/zend_persist.c index 05a7cb00077..eb339ee5a4f 100644 --- a/ext/opcache/zend_persist.c +++ b/ext/opcache/zend_persist.c @@ -1394,11 +1394,11 @@ static void zend_accel_persist_class_table(HashTable *class_table) zend_error_info **zend_persist_warnings(uint32_t num_warnings, zend_error_info **warnings) { if (warnings) { - warnings = zend_shared_memdup_free(warnings, num_warnings * sizeof(zend_error_info *)); + warnings = zend_shared_memdup(warnings, num_warnings * sizeof(zend_error_info *)); for (uint32_t i = 0; i < num_warnings; i++) { - warnings[i] = zend_shared_memdup_free(warnings[i], sizeof(zend_error_info)); zend_accel_store_string(warnings[i]->filename); zend_accel_store_string(warnings[i]->message); + warnings[i] = zend_shared_memdup(warnings[i], sizeof(zend_error_info)); } } return warnings; diff --git a/ext/opcache/zend_shared_alloc.c b/ext/opcache/zend_shared_alloc.c index 37dbe59f3d5..80ef36b8749 100644 --- a/ext/opcache/zend_shared_alloc.c +++ b/ext/opcache/zend_shared_alloc.c @@ -229,6 +229,9 @@ int zend_shared_alloc_startup(size_t requested_size, size_t reserved_size) if (!g_shared_alloc_handler) { /* try memory handlers in order */ + if (handler_table->name == NULL) { + return NO_SHM_BACKEND; + } for (he = handler_table; he->name; he++) { res = zend_shared_alloc_try(he, requested_size, &ZSMMG(shared_segments), &ZSMMG(shared_segments_count), &error_in); if (res) { diff --git a/ext/opcache/zend_shared_alloc.h b/ext/opcache/zend_shared_alloc.h index 41cba0bb351..108349b13f8 100644 --- a/ext/opcache/zend_shared_alloc.h +++ b/ext/opcache/zend_shared_alloc.h @@ -72,6 +72,7 @@ #define SUCCESSFULLY_REATTACHED 4 #define ALLOC_FAIL_MAPPING 8 #define ALLOC_FALLBACK 9 +#define NO_SHM_BACKEND 10 typedef struct _zend_shared_segment { size_t size; diff --git a/ext/openssl/config0.m4 b/ext/openssl/config0.m4 index 774213336b6..15d1feb96ee 100644 --- a/ext/openssl/config0.m4 +++ b/ext/openssl/config0.m4 @@ -49,9 +49,6 @@ if test "$PHP_OPENSSL" != "no"; then the default provider.])]) AS_VAR_IF([PHP_OPENSSL_ARGON2], [no],, [ - AS_VAR_IF([PHP_THREAD_SAFETY], [yes], - [AC_MSG_ERROR([Not supported in ZTS mode for now])]) - PHP_CHECK_LIBRARY([crypto], [OSSL_set_max_threads], [AC_DEFINE([HAVE_OPENSSL_ARGON2], [1], [Define to 1 to enable OpenSSL argon2 password hashing.])], diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c index 6b2fcd7898b..aefb02a3338 100644 --- a/ext/openssl/openssl.c +++ b/ext/openssl/openssl.c @@ -355,7 +355,15 @@ static PHP_INI_MH(OnUpdateLibCtx) { #if PHP_OPENSSL_API_VERSION >= 0x30000 if (zend_string_equals_literal(new_value, "default")) { +#if defined(ZTS) && defined(HAVE_OPENSSL_ARGON2) + if (stage != ZEND_INI_STAGE_DEACTIVATE) { + int err_type = stage == ZEND_INI_STAGE_RUNTIME ? E_WARNING : E_ERROR; + php_error_docref(NULL, err_type, "OpenSSL libctx \"default\" cannot be used in this configuration"); + } + return FAILURE; +#else OPENSSL_G(ctx).libctx = OPENSSL_G(ctx).default_libctx; +#endif } else if (zend_string_equals_literal(new_value, "custom")) { OPENSSL_G(ctx).libctx = OPENSSL_G(ctx).custom_libctx; } else { @@ -2348,6 +2356,14 @@ PHP_FUNCTION(openssl_pkey_derive) RETURN_THROWS(); } + if (ZEND_NUM_ARGS() == 3) { + php_error_docref(NULL, E_DEPRECATED, + "the $key_length parameter is deprecated as it is either ignored or truncates the key"); + if (UNEXPECTED(EG(exception))) { + RETURN_THROWS(); + } + } + if (key_len < 0) { zend_argument_value_error(3, "must be greater than or equal to 0"); RETURN_THROWS(); @@ -2733,7 +2749,7 @@ PHP_FUNCTION(openssl_pkcs7_read) goto clean_exit; } - p7 = PEM_read_bio_PKCS7(bio_in, NULL, NULL, NULL); + p7 = php_openssl_pem_read_bio_pkcs7(bio_in); if (p7 == NULL) { php_openssl_store_errors(); goto clean_exit; @@ -3055,19 +3071,19 @@ PHP_FUNCTION(openssl_cms_verify) switch (encoding) { case ENCODING_PEM: - cms = PEM_read_bio_CMS(sigbio, NULL, 0, NULL); - datain = in; - break; - case ENCODING_DER: - cms = d2i_CMS_bio(sigbio, NULL); - datain = in; - break; - case ENCODING_SMIME: - cms = SMIME_read_CMS(sigbio, &datain); - break; - default: - php_error_docref(NULL, E_WARNING, "Unknown encoding"); - goto clean_exit; + cms = php_openssl_pem_read_bio_cms(sigbio); + datain = in; + break; + case ENCODING_DER: + cms = php_openssl_d2i_bio_cms(sigbio); + datain = in; + break; + case ENCODING_SMIME: + cms = php_openssl_smime_read_cms(sigbio, &datain); + break; + default: + php_error_docref(NULL, E_WARNING, "Unknown encoding"); + goto clean_exit; } if (cms == NULL) { php_openssl_store_errors(); @@ -3185,6 +3201,7 @@ PHP_FUNCTION(openssl_cms_encrypt) X509 * cert; const EVP_CIPHER *cipher = NULL; zend_long cipherid = PHP_OPENSSL_CIPHER_DEFAULT; + zend_string *cipher_str = NULL; zend_string * strindex; char * infilename = NULL; size_t infilename_len; @@ -3194,11 +3211,16 @@ PHP_FUNCTION(openssl_cms_encrypt) RETVAL_FALSE; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "ppza!|lll", &infilename, &infilename_len, - &outfilename, &outfilename_len, &zrecipcerts, &zheaders, &flags, &encoding, &cipherid) == FAILURE) { - RETURN_THROWS(); - } - + ZEND_PARSE_PARAMETERS_START(4, 7) + Z_PARAM_PATH(infilename, infilename_len) + Z_PARAM_PATH(outfilename, outfilename_len) + Z_PARAM_ZVAL(zrecipcerts) + Z_PARAM_ARRAY_OR_NULL(zheaders) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(flags) + Z_PARAM_LONG(encoding) + Z_PARAM_STR_OR_LONG(cipher_str, cipherid) + ZEND_PARSE_PARAMETERS_END(); infile = php_openssl_bio_new_file( infilename, infilename_len, 1, PHP_OPENSSL_BIO_MODE_R(flags)); @@ -3257,7 +3279,11 @@ PHP_FUNCTION(openssl_cms_encrypt) } /* sanity check the cipher */ - cipher = php_openssl_get_evp_cipher_from_algo(cipherid); + if (cipher_str) { + cipher = php_openssl_get_evp_cipher_by_name(ZSTR_VAL(cipher_str)); + } else { + cipher = php_openssl_get_evp_cipher_from_algo(cipherid); + } if (cipher == NULL) { /* shouldn't happen */ php_error_docref(NULL, E_WARNING, "Failed to get cipher"); @@ -3382,7 +3408,7 @@ PHP_FUNCTION(openssl_cms_read) goto clean_exit; } - cms = PEM_read_bio_CMS(bio_in, NULL, NULL, NULL); + cms = php_openssl_pem_read_bio_cms(bio_in); if (cms == NULL) { php_openssl_store_errors(); goto clean_exit; @@ -3687,13 +3713,13 @@ PHP_FUNCTION(openssl_cms_decrypt) switch (encoding) { case ENCODING_DER: - cms = d2i_CMS_bio(in, NULL); + cms = php_openssl_d2i_bio_cms(in); break; case ENCODING_PEM: - cms = PEM_read_bio_CMS(in, NULL, 0, NULL); + cms = php_openssl_pem_read_bio_cms(in); break; case ENCODING_SMIME: - cms = SMIME_read_CMS(in, &datain); + cms = php_openssl_smime_read_cms(in, &datain); break; default: zend_argument_value_error(5, "must be an OPENSSL_ENCODING_* constant"); @@ -3725,6 +3751,29 @@ clean_exit: /* }}} */ +/* Helper to set RSA padding and digest for OAEP */ +static int php_openssl_set_rsa_padding_and_digest(EVP_PKEY_CTX *ctx, zend_long padding, const char *digest_algo, const EVP_MD **pmd) +{ + if (EVP_PKEY_CTX_set_rsa_padding(ctx, padding) <= 0) { + return 0; + } + + if (digest_algo != NULL) { + const EVP_MD *md = php_openssl_get_evp_md_by_name(digest_algo); + if (md == NULL) { + php_error_docref(NULL, E_WARNING, "Unknown digest algorithm: %s", digest_algo); + return 0; + } + *pmd = md; + if (padding == RSA_PKCS1_OAEP_PADDING) { + if (EVP_PKEY_CTX_set_rsa_oaep_md(ctx, md) <= 0) { + return 0; + } + } + } + + return 1; +} /* {{{ Encrypts data with private key */ PHP_FUNCTION(openssl_private_encrypt) @@ -3780,10 +3829,12 @@ PHP_FUNCTION(openssl_private_decrypt) { zval *key, *crypted; zend_long padding = RSA_PKCS1_PADDING; - char * data; - size_t data_len; + char *data; + char *digest_algo = NULL; + size_t data_len, digest_algo_len = 0; + const EVP_MD *md = NULL; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "szz|l", &data, &data_len, &crypted, &key, &padding) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "szz|lp!", &data, &data_len, &crypted, &key, &padding, &digest_algo, &digest_algo_len) == FAILURE) { RETURN_THROWS(); } @@ -3798,7 +3849,7 @@ PHP_FUNCTION(openssl_private_decrypt) size_t out_len = 0; EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(pkey, NULL); if (!ctx || EVP_PKEY_decrypt_init(ctx) <= 0 || - EVP_PKEY_CTX_set_rsa_padding(ctx, padding) <= 0 || + !php_openssl_set_rsa_padding_and_digest(ctx, padding, digest_algo, &md) || EVP_PKEY_decrypt(ctx, NULL, &out_len, (unsigned char *) data, data_len) <= 0) { php_openssl_store_errors(); RETVAL_FALSE; @@ -3820,6 +3871,7 @@ PHP_FUNCTION(openssl_private_decrypt) RETVAL_TRUE; cleanup: + php_openssl_release_evp_md(md); EVP_PKEY_CTX_free(ctx); EVP_PKEY_free(pkey); } @@ -3831,9 +3883,11 @@ PHP_FUNCTION(openssl_public_encrypt) zval *key, *crypted; zend_long padding = RSA_PKCS1_PADDING; char * data; - size_t data_len; + char *digest_algo = NULL; + size_t data_len, digest_algo_len = 0; + const EVP_MD *md = NULL; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "szz|l", &data, &data_len, &crypted, &key, &padding) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "szz|lp!", &data, &data_len, &crypted, &key, &padding, &digest_algo, &digest_algo_len) == FAILURE) { RETURN_THROWS(); } @@ -3848,7 +3902,7 @@ PHP_FUNCTION(openssl_public_encrypt) size_t out_len = 0; EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(pkey, NULL); if (!ctx || EVP_PKEY_encrypt_init(ctx) <= 0 || - EVP_PKEY_CTX_set_rsa_padding(ctx, padding) <= 0 || + !php_openssl_set_rsa_padding_and_digest(ctx, padding, digest_algo, &md) || EVP_PKEY_encrypt(ctx, NULL, &out_len, (unsigned char *) data, data_len) <= 0) { php_openssl_store_errors(); RETVAL_FALSE; @@ -3869,6 +3923,7 @@ PHP_FUNCTION(openssl_public_encrypt) RETVAL_TRUE; cleanup: + php_openssl_release_evp_md(md); EVP_PKEY_CTX_free(ctx); EVP_PKEY_free(pkey); } @@ -3879,7 +3934,7 @@ PHP_FUNCTION(openssl_public_decrypt) { zval *key, *crypted; zend_long padding = RSA_PKCS1_PADDING; - char * data; + char *data; size_t data_len; if (zend_parse_parameters(ZEND_NUM_ARGS(), "szz|l", &data, &data_len, &crypted, &key, &padding) == FAILURE) { @@ -3952,6 +4007,30 @@ PHP_FUNCTION(openssl_error_string) } /* }}} */ +static zend_result php_openssl_setup_rsa_padding(EVP_PKEY_CTX *pctx, EVP_PKEY *pkey, zend_long padding) +{ + int key_type = EVP_PKEY_type(EVP_PKEY_id(pkey)); + + if (padding != 0) { // 0 = default/unspecified + if (key_type != EVP_PKEY_RSA) { + php_error_docref(NULL, E_WARNING, "Padding parameter is only supported for RSA keys"); + return FAILURE; + } + + if (padding == RSA_PKCS1_PSS_PADDING) { + if (EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING) <= 0) { + php_openssl_store_errors(); + return FAILURE; + } + } else if (padding != RSA_PKCS1_PADDING) { + php_error_docref(NULL, E_WARNING, "Unknown padding type"); + return FAILURE; + } + } + + return SUCCESS; +} + /* {{{ Signs data */ PHP_FUNCTION(openssl_sign) { @@ -3964,14 +4043,17 @@ PHP_FUNCTION(openssl_sign) zend_string *method_str = NULL; zend_long method_long = OPENSSL_ALGO_SHA1; const EVP_MD *mdtype; + zend_long padding = 0; + EVP_PKEY_CTX *pctx; bool can_default_digest = ZEND_THREEWAY_COMPARE(PHP_OPENSSL_API_VERSION, 0x30000) >= 0; - ZEND_PARSE_PARAMETERS_START(3, 4) + ZEND_PARSE_PARAMETERS_START(3, 5) Z_PARAM_STRING(data, data_len) Z_PARAM_ZVAL(signature) Z_PARAM_ZVAL(key) Z_PARAM_OPTIONAL Z_PARAM_STR_OR_LONG(method_str, method_long) + Z_PARAM_LONG(padding) ZEND_PARSE_PARAMETERS_END(); pkey = php_openssl_pkey_from_zval(key, 0, "", 0, 3); @@ -3996,7 +4078,8 @@ PHP_FUNCTION(openssl_sign) md_ctx = EVP_MD_CTX_create(); size_t siglen; if (md_ctx != NULL && - EVP_DigestSignInit(md_ctx, NULL, mdtype, NULL, pkey) && + EVP_DigestSignInit(md_ctx, &pctx, mdtype, NULL, pkey) && + php_openssl_setup_rsa_padding(pctx, pkey, padding) == SUCCESS && EVP_DigestSign(md_ctx, NULL, &siglen, (unsigned char*)data, data_len) && (sigbuf = zend_string_alloc(siglen, 0)) != NULL && EVP_DigestSign(md_ctx, (unsigned char*)ZSTR_VAL(sigbuf), &siglen, (unsigned char*)data, data_len)) { @@ -4029,14 +4112,17 @@ PHP_FUNCTION(openssl_verify) size_t signature_len; zend_string *method_str = NULL; zend_long method_long = OPENSSL_ALGO_SHA1; + zend_long padding = 0; + EVP_PKEY_CTX *pctx; bool can_default_digest = ZEND_THREEWAY_COMPARE(PHP_OPENSSL_API_VERSION, 0x30000) >= 0; - ZEND_PARSE_PARAMETERS_START(3, 4) + ZEND_PARSE_PARAMETERS_START(3, 5) Z_PARAM_STRING(data, data_len) Z_PARAM_STRING(signature, signature_len) Z_PARAM_ZVAL(key) Z_PARAM_OPTIONAL Z_PARAM_STR_OR_LONG(method_str, method_long) + Z_PARAM_LONG(padding) ZEND_PARSE_PARAMETERS_END(); PHP_OPENSSL_CHECK_SIZE_T_TO_UINT(signature_len, signature, 2); @@ -4061,11 +4147,25 @@ PHP_FUNCTION(openssl_verify) } md_ctx = EVP_MD_CTX_create(); - if (md_ctx == NULL || - !EVP_DigestVerifyInit(md_ctx, NULL, mdtype, NULL, pkey) || - (err = EVP_DigestVerify(md_ctx, (unsigned char *)signature, signature_len, (unsigned char*)data, data_len)) < 0) { + if (md_ctx == NULL) { + php_openssl_store_errors(); + err = -1; + goto cleanup; + } + + if (!EVP_DigestVerifyInit(md_ctx, &pctx, mdtype, NULL, pkey) || + php_openssl_setup_rsa_padding(pctx, pkey, padding) == FAILURE) { + php_openssl_store_errors(); + err = -1; + goto cleanup; + } + + err = EVP_DigestVerify(md_ctx, (unsigned char *)signature, signature_len, (unsigned char*)data, data_len); + if (err < 0) { php_openssl_store_errors(); } + +cleanup: EVP_MD_CTX_destroy(md_ctx); php_openssl_release_evp_md(mdtype); EVP_PKEY_free(pkey); diff --git a/ext/openssl/openssl.stub.php b/ext/openssl/openssl.stub.php index 1fe3a9fc168..12cbb0ed618 100644 --- a/ext/openssl/openssl.stub.php +++ b/ext/openssl/openssl.stub.php @@ -166,6 +166,26 @@ const PKCS7_NOSIGS = UNKNOWN; * @cvalue PKCS7_NOOLDMIMETYPE */ const PKCS7_NOOLDMIMETYPE = UNKNOWN; +/** + * @var int + * @cvalue PKCS7_NOSMIMECAP + */ +const PKCS7_NOSMIMECAP = UNKNOWN; +/** + * @var int + * @cvalue PKCS7_CRLFEOL + */ +const PKCS7_CRLFEOL = UNKNOWN; +/** + * @var int + * @cvalue PKCS7_NOCRL + */ +const PKCS7_NOCRL = UNKNOWN; +/** + * @var int + * @cvalue PKCS7_NO_DUAL_CONTENT + */ +const PKCS7_NO_DUAL_CONTENT = UNKNOWN; /** * @var int @@ -236,6 +256,11 @@ const OPENSSL_NO_PADDING = UNKNOWN; * @cvalue RSA_PKCS1_OAEP_PADDING */ const OPENSSL_PKCS1_OAEP_PADDING = UNKNOWN; +/** + * @var int + * @cvalue RSA_PKCS1_PSS_PADDING + */ +const OPENSSL_PKCS1_PSS_PADDING = UNKNOWN; /* Informational stream wrapper constants */ @@ -549,7 +574,7 @@ function openssl_pkcs7_read(string $data, &$certificates): bool {} function openssl_cms_verify(string $input_filename, int $flags = 0, ?string $certificates = null, array $ca_info = [], ?string $untrusted_certificates_filename = null, ?string $content = null, ?string $pk7 = null, ?string $sigfile = null, int $encoding = OPENSSL_ENCODING_SMIME): bool {} /** @param OpenSSLCertificate|array|string $certificate */ -function openssl_cms_encrypt(string $input_filename, string $output_filename, $certificate, ?array $headers, int $flags = 0, int $encoding = OPENSSL_ENCODING_SMIME, int $cipher_algo = OPENSSL_CIPHER_AES_128_CBC): bool {} +function openssl_cms_encrypt(string $input_filename, string $output_filename, $certificate, ?array $headers, int $flags = 0, int $encoding = OPENSSL_ENCODING_SMIME, string|int $cipher_algo = OPENSSL_CIPHER_AES_128_CBC): bool {} /** * @param OpenSSLAsymmetricKey|OpenSSLCertificate|array|string $private_key @@ -575,13 +600,13 @@ function openssl_private_encrypt(#[\SensitiveParameter] string $data, &$encrypte * @param string $decrypted_data * @param OpenSSLAsymmetricKey|OpenSSLCertificate|array|string $private_key */ -function openssl_private_decrypt(string $data, #[\SensitiveParameter] &$decrypted_data, #[\SensitiveParameter] $private_key, int $padding = OPENSSL_PKCS1_PADDING): bool {} +function openssl_private_decrypt(string $data, #[\SensitiveParameter] &$decrypted_data, #[\SensitiveParameter] $private_key, int $padding = OPENSSL_PKCS1_PADDING, ?string $digest_algo = null): bool {} /** * @param string $encrypted_data * @param OpenSSLAsymmetricKey|OpenSSLCertificate|array|string $public_key */ -function openssl_public_encrypt(#[\SensitiveParameter] string $data, &$encrypted_data, $public_key, int $padding = OPENSSL_PKCS1_PADDING): bool {} +function openssl_public_encrypt(#[\SensitiveParameter] string $data, &$encrypted_data, $public_key, int $padding = OPENSSL_PKCS1_PADDING, ?string $digest_algo = null): bool {} /** * @param string $decrypted_data @@ -595,10 +620,10 @@ function openssl_error_string(): string|false {} * @param string $signature * @param OpenSSLAsymmetricKey|OpenSSLCertificate|array|string $private_key */ -function openssl_sign(string $data, &$signature, #[\SensitiveParameter] $private_key, string|int $algorithm = OPENSSL_ALGO_SHA1): bool {} +function openssl_sign(string $data, &$signature, #[\SensitiveParameter] $private_key, string|int $algorithm = OPENSSL_ALGO_SHA1, int $padding = 0): bool {} /** @param OpenSSLAsymmetricKey|OpenSSLCertificate|array|string $public_key */ -function openssl_verify(string $data, string $signature, $public_key, string|int $algorithm = OPENSSL_ALGO_SHA1): int|false {} +function openssl_verify(string $data, string $signature, $public_key, string|int $algorithm = OPENSSL_ALGO_SHA1, int $padding = 0): int|false {} /** * @param string $sealed_data diff --git a/ext/openssl/openssl_arginfo.h b/ext/openssl/openssl_arginfo.h index 75936b3671f..44415a75892 100644 --- a/ext/openssl/openssl_arginfo.h +++ b/ext/openssl/openssl_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: a42bd7dec0a5e011983ce08b5e31cd8718247501 */ + * Stub hash: 0e6a5f1a5f23602bafd5b7fdb10525c19a9476fc */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_openssl_x509_export_to_file, 0, 2, _IS_BOOL, 0) ZEND_ARG_OBJ_TYPE_MASK(0, certificate, OpenSSLCertificate, MAY_BE_STRING, NULL) @@ -219,7 +219,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_openssl_cms_encrypt, 0, 4, _IS_B ZEND_ARG_TYPE_INFO(0, headers, IS_ARRAY, 1) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, flags, IS_LONG, 0, "0") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, encoding, IS_LONG, 0, "OPENSSL_ENCODING_SMIME") - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, cipher_algo, IS_LONG, 0, "OPENSSL_CIPHER_AES_128_CBC") + ZEND_ARG_TYPE_MASK(0, cipher_algo, MAY_BE_STRING|MAY_BE_LONG, "OPENSSL_CIPHER_AES_128_CBC") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_openssl_cms_sign, 0, 5, _IS_BOOL, 0) @@ -258,6 +258,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_openssl_private_decrypt, 0, 3, _ ZEND_ARG_INFO(1, decrypted_data) ZEND_ARG_INFO(0, private_key) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, padding, IS_LONG, 0, "OPENSSL_PKCS1_PADDING") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, digest_algo, IS_STRING, 1, "null") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_openssl_public_encrypt, 0, 3, _IS_BOOL, 0) @@ -265,6 +266,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_openssl_public_encrypt, 0, 3, _I ZEND_ARG_INFO(1, encrypted_data) ZEND_ARG_INFO(0, public_key) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, padding, IS_LONG, 0, "OPENSSL_PKCS1_PADDING") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, digest_algo, IS_STRING, 1, "null") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_openssl_public_decrypt, 0, 3, _IS_BOOL, 0) @@ -282,6 +284,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_openssl_sign, 0, 3, _IS_BOOL, 0) ZEND_ARG_INFO(1, signature) ZEND_ARG_INFO(0, private_key) ZEND_ARG_TYPE_MASK(0, algorithm, MAY_BE_STRING|MAY_BE_LONG, "OPENSSL_ALGO_SHA1") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, padding, IS_LONG, 0, "0") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_openssl_verify, 0, 3, MAY_BE_LONG|MAY_BE_FALSE) @@ -289,6 +292,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_openssl_verify, 0, 3, MAY_BE_LON ZEND_ARG_TYPE_INFO(0, signature, IS_STRING, 0) ZEND_ARG_INFO(0, public_key) ZEND_ARG_TYPE_MASK(0, algorithm, MAY_BE_STRING|MAY_BE_LONG, "OPENSSL_ALGO_SHA1") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, padding, IS_LONG, 0, "0") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_openssl_seal, 0, 5, MAY_BE_LONG|MAY_BE_FALSE) @@ -582,6 +586,10 @@ static void register_openssl_symbols(int module_number) REGISTER_LONG_CONSTANT("PKCS7_BINARY", PKCS7_BINARY, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("PKCS7_NOSIGS", PKCS7_NOSIGS, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("PKCS7_NOOLDMIMETYPE", PKCS7_NOOLDMIMETYPE, CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("PKCS7_NOSMIMECAP", PKCS7_NOSMIMECAP, CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("PKCS7_CRLFEOL", PKCS7_CRLFEOL, CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("PKCS7_NOCRL", PKCS7_NOCRL, CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("PKCS7_NO_DUAL_CONTENT", PKCS7_NO_DUAL_CONTENT, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("OPENSSL_CMS_DETACHED", CMS_DETACHED, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("OPENSSL_CMS_TEXT", CMS_TEXT, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("OPENSSL_CMS_NOINTERN", CMS_NOINTERN, CONST_PERSISTENT); @@ -597,6 +605,7 @@ static void register_openssl_symbols(int module_number) #endif REGISTER_LONG_CONSTANT("OPENSSL_NO_PADDING", RSA_NO_PADDING, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("OPENSSL_PKCS1_OAEP_PADDING", RSA_PKCS1_OAEP_PADDING, CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("OPENSSL_PKCS1_PSS_PADDING", RSA_PKCS1_PSS_PADDING, CONST_PERSISTENT); REGISTER_STRING_CONSTANT("OPENSSL_DEFAULT_STREAM_CIPHERS", OPENSSL_DEFAULT_STREAM_CIPHERS, CONST_PERSISTENT); #if !defined(OPENSSL_NO_RC2) REGISTER_LONG_CONSTANT("OPENSSL_CIPHER_RC2_40", PHP_OPENSSL_CIPHER_RC2_40, CONST_PERSISTENT); @@ -642,10 +651,8 @@ static void register_openssl_symbols(int module_number) zend_attribute *attribute_Deprecated_func_openssl_x509_free_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "openssl_x509_free", sizeof("openssl_x509_free") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_func_openssl_x509_free_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_func_openssl_x509_free_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_openssl_x509_free_0_arg1; zend_string *attribute_Deprecated_func_openssl_x509_free_0_arg1_str = zend_string_init("as OpenSSLCertificate objects are freed automatically", strlen("as OpenSSLCertificate objects are freed automatically"), 1); - ZVAL_STR(&attribute_Deprecated_func_openssl_x509_free_0_arg1, attribute_Deprecated_func_openssl_x509_free_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_openssl_x509_free_0->args[1].value, &attribute_Deprecated_func_openssl_x509_free_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_openssl_x509_free_0->args[1].value, attribute_Deprecated_func_openssl_x509_free_0_arg1_str); attribute_Deprecated_func_openssl_x509_free_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_add_parameter_attribute(zend_hash_str_find_ptr(CG(function_table), "openssl_pkcs12_export_to_file", sizeof("openssl_pkcs12_export_to_file") - 1), 2, ZSTR_KNOWN(ZEND_STR_SENSITIVEPARAMETER), 0); @@ -673,19 +680,14 @@ static void register_openssl_symbols(int module_number) zend_attribute *attribute_Deprecated_func_openssl_pkey_free_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "openssl_pkey_free", sizeof("openssl_pkey_free") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_func_openssl_pkey_free_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_func_openssl_pkey_free_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_openssl_pkey_free_0_arg1; zend_string *attribute_Deprecated_func_openssl_pkey_free_0_arg1_str = zend_string_init("as OpenSSLAsymmetricKey objects are freed automatically", strlen("as OpenSSLAsymmetricKey objects are freed automatically"), 1); - ZVAL_STR(&attribute_Deprecated_func_openssl_pkey_free_0_arg1, attribute_Deprecated_func_openssl_pkey_free_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_openssl_pkey_free_0->args[1].value, &attribute_Deprecated_func_openssl_pkey_free_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_openssl_pkey_free_0->args[1].value, attribute_Deprecated_func_openssl_pkey_free_0_arg1_str); attribute_Deprecated_func_openssl_pkey_free_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_func_openssl_free_key_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "openssl_free_key", sizeof("openssl_free_key") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_func_openssl_free_key_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_func_openssl_free_key_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_openssl_free_key_0_arg1; - zend_string *attribute_Deprecated_func_openssl_free_key_0_arg1_str = zend_string_init("as OpenSSLAsymmetricKey objects are freed automatically", strlen("as OpenSSLAsymmetricKey objects are freed automatically"), 1); - ZVAL_STR(&attribute_Deprecated_func_openssl_free_key_0_arg1, attribute_Deprecated_func_openssl_free_key_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_openssl_free_key_0->args[1].value, &attribute_Deprecated_func_openssl_free_key_0_arg1); + ZVAL_STR_COPY(&attribute_Deprecated_func_openssl_free_key_0->args[1].value, attribute_Deprecated_func_openssl_pkey_free_0_arg1_str); attribute_Deprecated_func_openssl_free_key_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_add_parameter_attribute(zend_hash_str_find_ptr(CG(function_table), "openssl_pkey_get_private", sizeof("openssl_pkey_get_private") - 1), 0, ZSTR_KNOWN(ZEND_STR_SENSITIVEPARAMETER), 0); diff --git a/ext/openssl/openssl_backend_common.c b/ext/openssl/openssl_backend_common.c index 4dc8fd27f22..cde3848b40c 100644 --- a/ext/openssl/openssl_backend_common.c +++ b/ext/openssl/openssl_backend_common.c @@ -440,7 +440,7 @@ zend_result php_openssl_load_rand_file(const char * file, int *egdsocket, int *s return SUCCESS; #endif } - if (file == NULL || !RAND_load_file(file, -1)) { + if (file == NULL || RAND_load_file(file, -1) < 0) { if (RAND_status() == 0) { php_openssl_store_errors(); php_error_docref(NULL, E_WARNING, "Unable to load random state; not enough random data!"); @@ -465,7 +465,7 @@ zend_result php_openssl_write_rand_file(const char * file, int egdsocket, int se if (file == NULL) { file = RAND_file_name(buffer, sizeof(buffer)); } - if (file == NULL || !RAND_write_file(file)) { + if (file == NULL || RAND_write_file(file) < 0) { php_openssl_store_errors(); php_error_docref(NULL, E_WARNING, "Unable to write random state"); return FAILURE; @@ -541,18 +541,14 @@ X509 *php_openssl_x509_from_str( php_openssl_store_errors(); return NULL; } - cert = PEM_read_bio_X509(in, NULL, NULL, NULL); + cert = php_openssl_pem_read_bio_x509(in); } else { in = BIO_new_mem_buf(ZSTR_VAL(cert_str), (int) ZSTR_LEN(cert_str)); if (in == NULL) { php_openssl_store_errors(); return NULL; } -#ifdef TYPEDEF_D2I_OF - cert = (X509 *) PEM_ASN1_read_bio((d2i_of_void *)d2i_X509, PEM_STRING_X509, in, NULL, NULL, NULL); -#else - cert = (X509 *) PEM_ASN1_read_bio((char *(*)())d2i_X509, PEM_STRING_X509, in, NULL, NULL, NULL); -#endif + cert = php_openssl_pem_read_asn1_bio_x509(in); } if (!BIO_free(in)) { @@ -1127,7 +1123,7 @@ X509_REQ *php_openssl_csr_from_str(zend_string *csr_str, uint32_t arg_num) return NULL; } - csr = PEM_read_bio_X509_REQ(in, NULL,NULL,NULL); + csr = php_openssl_pem_read_bio_x509_req(in); if (csr == NULL) { php_openssl_store_errors(); } @@ -1158,7 +1154,7 @@ EVP_PKEY *php_openssl_extract_public_key(EVP_PKEY *priv_key) return NULL; } - EVP_PKEY *pub_key = PEM_read_bio_PUBKEY(bio, NULL, NULL, NULL); + EVP_PKEY *pub_key = php_openssl_pem_read_bio_public_key(bio); BIO_free(bio); return pub_key; } @@ -1290,7 +1286,7 @@ EVP_PKEY *php_openssl_pkey_from_zval( zend_string_release_ex(val_str, false); TMP_CLEAN; } - key = PEM_read_bio_PUBKEY(in, NULL,NULL, NULL); + key = php_openssl_pem_read_bio_public_key(in); BIO_free(in); } } else { @@ -1308,12 +1304,12 @@ EVP_PKEY *php_openssl_pkey_from_zval( TMP_CLEAN; } if (passphrase == NULL) { - key = PEM_read_bio_PrivateKey(in, NULL, NULL, NULL); + key = php_openssl_pem_read_bio_private_key(in, NULL, NULL); } else { struct php_openssl_pem_password password; password.key = passphrase; password.len = passphrase_len; - key = PEM_read_bio_PrivateKey(in, NULL, php_openssl_pem_password_cb, &password); + key = php_openssl_pem_read_bio_private_key(in, php_openssl_pem_password_cb, &password); } BIO_free(in); } @@ -1344,13 +1340,20 @@ EVP_PKEY *php_openssl_pkey_from_zval( return key; } -zend_string *php_openssl_pkey_derive(EVP_PKEY *key, EVP_PKEY *peer_key, size_t key_size) -{ - EVP_PKEY_CTX *ctx = php_openssl_pkey_new_from_pkey(key); +zend_string *php_openssl_pkey_derive(EVP_PKEY *key, EVP_PKEY *peer_key, size_t requested_key_size) { + size_t key_size = requested_key_size; + EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(key, NULL); if (!ctx) { return NULL; } +#if OPENSSL_VERSION_NUMBER < 0x30000000L + /* OpenSSL 1.1 does not respect key_size for DH, so force size discovery so it can be compared later. */ + if (EVP_PKEY_base_id(key) == EVP_PKEY_DH && key_size != 0) { + key_size = 0; + } +#endif + if (EVP_PKEY_derive_init(ctx) <= 0 || EVP_PKEY_derive_set_peer(ctx, peer_key) <= 0 || (key_size == 0 && EVP_PKEY_derive(ctx, NULL, &key_size) <= 0)) { @@ -1359,6 +1362,14 @@ zend_string *php_openssl_pkey_derive(EVP_PKEY *key, EVP_PKEY *peer_key, size_t k return NULL; } +#if OPENSSL_VERSION_NUMBER < 0x30000000L + /* Now compare the computed size for DH to mirror OpenSSL 3.0+ behavior. */ + if (EVP_PKEY_base_id(key) == EVP_PKEY_DH && requested_key_size > 0 && requested_key_size < key_size) { + EVP_PKEY_CTX_free(ctx); + return NULL; + } +#endif + zend_string *result = zend_string_alloc(key_size, 0); if (EVP_PKEY_derive(ctx, (unsigned char *)ZSTR_VAL(result), &key_size) <= 0) { php_openssl_store_errors(); @@ -1671,7 +1682,7 @@ zend_result php_openssl_validate_iv(const char **piv, size_t *piv_len, size_t iv char *iv_new; if (mode->is_aead) { - if (EVP_CIPHER_CTX_ctrl(cipher_ctx, mode->aead_ivlen_flag, *piv_len, NULL) != 1) { + if (EVP_CIPHER_CTX_ctrl(cipher_ctx, mode->aead_ivlen_flag, *piv_len, NULL) <= 0) { php_error_docref(NULL, E_WARNING, "Setting of IV length for AEAD mode failed"); return FAILURE; } @@ -1742,7 +1753,7 @@ zend_result php_openssl_cipher_init(const EVP_CIPHER *cipher_type, return FAILURE; } if (mode->set_tag_length_always || (enc && mode->set_tag_length_when_encrypting)) { - if (!EVP_CIPHER_CTX_ctrl(cipher_ctx, mode->aead_set_tag_flag, tag_len, NULL)) { + if (EVP_CIPHER_CTX_ctrl(cipher_ctx, mode->aead_set_tag_flag, tag_len, NULL) <= 0) { php_error_docref(NULL, E_WARNING, "Setting tag length for AEAD cipher failed"); return FAILURE; } @@ -1750,7 +1761,7 @@ zend_result php_openssl_cipher_init(const EVP_CIPHER *cipher_type, if (!enc && tag && tag_len > 0) { if (!mode->is_aead) { php_error_docref(NULL, E_WARNING, "The tag cannot be used because the cipher algorithm does not support AEAD"); - } else if (!EVP_CIPHER_CTX_ctrl(cipher_ctx, mode->aead_set_tag_flag, tag_len, (unsigned char *) tag)) { + } else if (EVP_CIPHER_CTX_ctrl(cipher_ctx, mode->aead_set_tag_flag, tag_len, (unsigned char *) tag) <= 0) { php_error_docref(NULL, E_WARNING, "Setting tag for AEAD cipher decryption failed"); return FAILURE; } @@ -1886,7 +1897,7 @@ PHP_OPENSSL_API zend_string* php_openssl_encrypt( if (mode.is_aead && tag) { zend_string *tag_str = zend_string_alloc(tag_len, 0); - if (EVP_CIPHER_CTX_ctrl(cipher_ctx, mode.aead_get_tag_flag, tag_len, ZSTR_VAL(tag_str)) == 1) { + if (EVP_CIPHER_CTX_ctrl(cipher_ctx, mode.aead_get_tag_flag, tag_len, ZSTR_VAL(tag_str)) > 0) { ZSTR_VAL(tag_str)[tag_len] = '\0'; ZSTR_LEN(tag_str) = tag_len; ZEND_TRY_ASSIGN_REF_NEW_STR(tag, tag_str); diff --git a/ext/openssl/openssl_backend_v1.c b/ext/openssl/openssl_backend_v1.c index ea9bd231915..c15fff2f795 100644 --- a/ext/openssl/openssl_backend_v1.c +++ b/ext/openssl/openssl_backend_v1.c @@ -692,4 +692,49 @@ CONF *php_openssl_nconf_new(void) return NCONF_new(NULL); } +X509 *php_openssl_pem_read_asn1_bio_x509(BIO *in) +{ + return PEM_ASN1_read_bio((d2i_of_void *)d2i_X509, PEM_STRING_X509, in, NULL, NULL, NULL); +} + +X509 *php_openssl_pem_read_bio_x509(BIO *in) +{ + return PEM_read_bio_X509(in, NULL, NULL, NULL); +} + +X509_REQ *php_openssl_pem_read_bio_x509_req(BIO *in) +{ + return PEM_read_bio_X509_REQ(in, NULL, NULL, NULL); +} + +EVP_PKEY *php_openssl_pem_read_bio_public_key(BIO *in) +{ + return PEM_read_bio_PUBKEY(in, NULL, NULL, NULL); +} + +EVP_PKEY *php_openssl_pem_read_bio_private_key(BIO *in, pem_password_cb *cb, void *u) +{ + return PEM_read_bio_PrivateKey(in, NULL, cb, u); +} + +PKCS7 *php_openssl_pem_read_bio_pkcs7(BIO *in) +{ + return PEM_read_bio_PKCS7(in, NULL, NULL, NULL); +} + +CMS_ContentInfo *php_openssl_pem_read_bio_cms(BIO *in) +{ + return PEM_read_bio_CMS(in, NULL, NULL, NULL); +} + +CMS_ContentInfo *php_openssl_d2i_bio_cms(BIO *in) +{ + return d2i_CMS_bio(in, NULL); +} + +CMS_ContentInfo *php_openssl_smime_read_cms(BIO *bio, BIO **bcont) +{ + return SMIME_read_CMS(bio, bcont); +} + #endif diff --git a/ext/openssl/openssl_backend_v3.c b/ext/openssl/openssl_backend_v3.c index 1b00581e7df..16f145b2c5f 100644 --- a/ext/openssl/openssl_backend_v3.c +++ b/ext/openssl/openssl_backend_v3.c @@ -713,6 +713,12 @@ zend_string *php_openssl_dh_compute_key(EVP_PKEY *pkey, char *pub_str, size_t pu const EVP_MD *php_openssl_get_evp_md_by_name(const char *name) { + const EVP_MD *dp = (const EVP_MD *) OBJ_NAME_get(name, OBJ_NAME_TYPE_MD_METH); + + if (dp != NULL) { + return dp; + } + return EVP_MD_fetch(PHP_OPENSSL_LIBCTX, name, PHP_OPENSSL_PROPQ); } @@ -769,6 +775,12 @@ static const char *php_openssl_cipher_names[] = { const EVP_CIPHER *php_openssl_get_evp_cipher_by_name(const char *name) { + const EVP_CIPHER *cp = (const EVP_CIPHER *) OBJ_NAME_get(name, OBJ_NAME_TYPE_CIPHER_METH); + + if (cp != NULL) { + return cp; + } + return EVP_CIPHER_fetch(PHP_OPENSSL_LIBCTX, name, PHP_OPENSSL_PROPQ); } @@ -831,4 +843,126 @@ CONF *php_openssl_nconf_new(void) return NCONF_new_ex(PHP_OPENSSL_LIBCTX, NULL); } +X509 *php_openssl_pem_read_asn1_bio_x509(BIO *in) +{ + X509 *x = X509_new_ex(PHP_OPENSSL_LIBCTX, PHP_OPENSSL_PROPQ); + + if (x == NULL) { + return NULL; + } + + if (PEM_ASN1_read_bio((d2i_of_void *)d2i_X509, PEM_STRING_X509, in, (void **) &x, NULL, NULL) == NULL) { + X509_free(x); + return NULL; + } + + return x; +} + +X509 *php_openssl_pem_read_bio_x509(BIO *in) +{ + X509 *x = X509_new_ex(PHP_OPENSSL_LIBCTX, PHP_OPENSSL_PROPQ); + + if (x == NULL) { + return NULL; + } + + if (PEM_read_bio_X509(in, &x, NULL, NULL) == NULL) { + X509_free(x); + return NULL; + } + + return x; +} + +X509_REQ *php_openssl_pem_read_bio_x509_req(BIO *in) +{ + X509_REQ *xr = X509_REQ_new_ex(PHP_OPENSSL_LIBCTX, PHP_OPENSSL_PROPQ); + + if (xr == NULL) { + return NULL; + } + + if (PEM_read_bio_X509_REQ(in, &xr, NULL, NULL) == NULL) { + X509_REQ_free(xr); + return NULL; + } + + return xr; +} + +EVP_PKEY *php_openssl_pem_read_bio_public_key(BIO *in) +{ + return PEM_read_bio_PUBKEY_ex(in, NULL, NULL, NULL, PHP_OPENSSL_LIBCTX, PHP_OPENSSL_PROPQ); +} + +EVP_PKEY *php_openssl_pem_read_bio_private_key(BIO *in, pem_password_cb *cb, void *u) +{ + return PEM_read_bio_PrivateKey_ex(in, NULL, cb, u, PHP_OPENSSL_LIBCTX, PHP_OPENSSL_PROPQ); +} + +PKCS7 *php_openssl_pem_read_bio_pkcs7(BIO *in) +{ + PKCS7 *p = PKCS7_new_ex(PHP_OPENSSL_LIBCTX, PHP_OPENSSL_PROPQ); + + if (p == NULL) { + return NULL; + } + + if (PEM_read_bio_PKCS7(in, &p, NULL, NULL) == NULL) { + PKCS7_free(p); + return NULL; + } + + return p; +} + +CMS_ContentInfo *php_openssl_pem_read_bio_cms(BIO *in) +{ + CMS_ContentInfo *ci = CMS_ContentInfo_new_ex(PHP_OPENSSL_LIBCTX, PHP_OPENSSL_PROPQ); + + if (ci == NULL) { + return NULL; + } + + if (PEM_read_bio_CMS(in, &ci, NULL, NULL) == NULL) { + CMS_ContentInfo_free(ci); + return NULL; + } + + return ci; +} + +CMS_ContentInfo *php_openssl_d2i_bio_cms(BIO *in) +{ + CMS_ContentInfo *ci = CMS_ContentInfo_new_ex(PHP_OPENSSL_LIBCTX, PHP_OPENSSL_PROPQ); + + if (ci == NULL) { + return NULL; + } + + if (d2i_CMS_bio(in, &ci) == NULL) { + CMS_ContentInfo_free(ci); + return NULL; + } + + return ci; +} + +CMS_ContentInfo *php_openssl_smime_read_cms(BIO *bio, BIO **bcont) +{ + CMS_ContentInfo *ci = CMS_ContentInfo_new_ex(PHP_OPENSSL_LIBCTX, PHP_OPENSSL_PROPQ); + + if (ci == NULL) { + return NULL; + } + + if (SMIME_read_CMS_ex(bio, 0, bcont, &ci) == NULL) { + CMS_ContentInfo_free(ci); + return NULL; + } + + return ci; +} + #endif diff --git a/ext/openssl/openssl_pwhash.c b/ext/openssl/openssl_pwhash.c index 5fe5bb5cf1b..dc125e3b516 100644 --- a/ext/openssl/openssl_pwhash.c +++ b/ext/openssl/openssl_pwhash.c @@ -22,7 +22,7 @@ #include "ext/standard/php_password.h" #include "php_openssl.h" -#if defined(HAVE_OPENSSL_ARGON2) +#ifdef HAVE_OPENSSL_ARGON2 #include "Zend/zend_attributes.h" #include "openssl_pwhash_arginfo.h" #include @@ -46,6 +46,8 @@ #define PHP_OPENSSL_HASH_SIZE 32 #define PHP_OPENSSL_DIGEST_SIZE 128 +ZEND_EXTERN_MODULE_GLOBALS(openssl) + static inline zend_result get_options(zend_array *options, uint32_t *memlimit, uint32_t *iterlimit, uint32_t *threads) { zval *opt; @@ -98,8 +100,8 @@ static bool php_openssl_argon2_compute_hash( uint32_t oldthreads; bool ret = false; - oldthreads = OSSL_get_max_threads(NULL); - if (OSSL_set_max_threads(NULL, threads) != 1) { + oldthreads = OSSL_get_max_threads(PHP_OPENSSL_LIBCTX); + if (OSSL_set_max_threads(PHP_OPENSSL_LIBCTX, threads) != 1) { goto fail; } p = params; @@ -111,7 +113,7 @@ static bool php_openssl_argon2_compute_hash( *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_PASSWORD, (void *)pass, pass_len); *p++ = OSSL_PARAM_construct_end(); - if ((kdf = EVP_KDF_fetch(NULL, algo, NULL)) == NULL) { + if ((kdf = EVP_KDF_fetch(PHP_OPENSSL_LIBCTX, algo, PHP_OPENSSL_PROPQ)) == NULL) { goto fail; } if ((kctx = EVP_KDF_CTX_new(kdf)) == NULL) { @@ -127,7 +129,7 @@ static bool php_openssl_argon2_compute_hash( fail: EVP_KDF_free(kdf); EVP_KDF_CTX_free(kctx); - OSSL_set_max_threads(NULL, oldthreads); + OSSL_set_max_threads(PHP_OPENSSL_LIBCTX, oldthreads); return ret; } @@ -385,4 +387,5 @@ PHP_MINIT_FUNCTION(openssl_pwhash) return SUCCESS; } + #endif /* HAVE_OPENSSL_ARGON2 */ diff --git a/ext/openssl/php_openssl_backend.h b/ext/openssl/php_openssl_backend.h index 86111e2997d..35af52c6c83 100644 --- a/ext/openssl/php_openssl_backend.h +++ b/ext/openssl/php_openssl_backend.h @@ -190,7 +190,17 @@ X509_STORE * php_openssl_setup_verify(zval * calist, uint32_t arg_num); STACK_OF(X509) * php_openssl_load_all_certs_from_file( char *cert_file, size_t cert_file_len, uint32_t arg_num); EVP_PKEY * php_openssl_generate_private_key(struct php_x509_request * req); -zend_string *php_openssl_pkey_derive(EVP_PKEY *key, EVP_PKEY *peer_key, size_t key_size); +zend_string *php_openssl_pkey_derive(EVP_PKEY *key, EVP_PKEY *peer_key, size_t requested_key_size); + +X509 *php_openssl_pem_read_asn1_bio_x509(BIO *in); +X509 *php_openssl_pem_read_bio_x509(BIO *in); +X509_REQ *php_openssl_pem_read_bio_x509_req(BIO *in); +EVP_PKEY *php_openssl_pem_read_bio_public_key(BIO *in); +EVP_PKEY *php_openssl_pem_read_bio_private_key(BIO *in, pem_password_cb *cb, void *u); +PKCS7 *php_openssl_pem_read_bio_pkcs7(BIO *in); +CMS_ContentInfo *php_openssl_pem_read_bio_cms(BIO *in); +CMS_ContentInfo *php_openssl_d2i_bio_cms(BIO *in); +CMS_ContentInfo *php_openssl_smime_read_cms(BIO *bio, BIO **bcont); #define PHP_SSL_REQ_INIT(req) memset(req, 0, sizeof(*req)) #define PHP_SSL_REQ_DISPOSE(req) php_openssl_dispose_config(req) diff --git a/ext/openssl/tests/check_default_conf_path.phpt b/ext/openssl/tests/check_default_conf_path.phpt index 4590ef7804d..267bebe16c1 100644 --- a/ext/openssl/tests/check_default_conf_path.phpt +++ b/ext/openssl/tests/check_default_conf_path.phpt @@ -21,7 +21,7 @@ ob_end_clean(); preg_match(",Openssl default config [^ ]* (.*),", $info, $m); if (isset($m[1])) { - var_dump(str_replace('/', '\\', strtolower($m[1]))); + var_dump(str_replace('\\/', '\\', strtolower($m[1]))); } else { echo $info; } diff --git a/ext/openssl/tests/gh19245.phpt b/ext/openssl/tests/gh19245.phpt new file mode 100644 index 00000000000..13433cc42a3 --- /dev/null +++ b/ext/openssl/tests/gh19245.phpt @@ -0,0 +1,53 @@ +--TEST-- +GH-19245: Success error message on TLS stream accept failure +--EXTENSIONS-- +openssl +--SKIPIF-- + +--FILE-- + [ + 'local_cert' => '%s', + 'local_pk' => '%s', + ]]); + + $sock = stream_socket_server($serverUri, $errno, $errstr, $serverFlags, $serverCtx); + phpt_notify_server_start($sock); + + $link = stream_socket_accept($sock); +CODE; + +$clientCode = <<<'CODE' + $serverUri = "ssl://{{ ADDR }}"; + $clientFlags = STREAM_CLIENT_CONNECT; + + $clientCtx = stream_context_create(['ssl' => [ + 'verify_peer' => false, + 'verify_peer_name' => false + ]]); + + @stream_socket_client($serverUri, $errno, $errstr, 2, $clientFlags, $clientCtx); +CODE; + +$serverCode = sprintf($serverCodeTemplate, $baseDirCertFile . "\0test", $baseDirPkFile); +ServerClientTestCase::getInstance()->run($clientCode, $serverCode); + +?> +--EXPECTF-- +PHP Warning: stream_socket_accept(): Path for local_cert in ssl stream context option must not contain any null bytes in %s +PHP Warning: stream_socket_accept(): Unable to get real path of certificate file `%scert.crt' in %s +PHP Warning: stream_socket_accept(): Failed to enable crypto in %s +PHP Warning: stream_socket_accept(): Accept failed: Cannot enable crypto in %s diff --git a/ext/openssl/tests/gh19369.phpt b/ext/openssl/tests/gh19369.phpt new file mode 100644 index 00000000000..3568bbbfeaf --- /dev/null +++ b/ext/openssl/tests/gh19369.phpt @@ -0,0 +1,20 @@ +--TEST-- +GH-19369: openssl_sign with alias algorithms +--EXTENSIONS-- +openssl +--SKIPIF-- + +--FILE-- + +--EXPECT-- +bool(true) diff --git a/ext/openssl/tests/gh19428.phpt b/ext/openssl/tests/gh19428.phpt new file mode 100644 index 00000000000..373b49b5253 --- /dev/null +++ b/ext/openssl/tests/gh19428.phpt @@ -0,0 +1,45 @@ +--TEST-- +GH-19428: openssl_pkey_derive() DH with low key_length +--EXTENSIONS-- +openssl +--FILE-- + +--EXPECTF-- +Deprecated: openssl_pkey_derive(): the $key_length parameter is deprecated as it is either ignored or truncates the key in %s on line %d +bool(false) diff --git a/ext/openssl/tests/openssl_cms_encrypt_auth_env.phpt b/ext/openssl/tests/openssl_cms_encrypt_auth_env.phpt new file mode 100644 index 00000000000..9b2086c78ac --- /dev/null +++ b/ext/openssl/tests/openssl_cms_encrypt_auth_env.phpt @@ -0,0 +1,34 @@ +--TEST-- +openssl_cms_encrypt() auth enveloped data tests +--EXTENSIONS-- +openssl +--SKIPIF-- += 3.0'); +?> +--FILE-- + +--CLEAN-- + +--EXPECT-- +bool(true) +bool(true) +bool(true) +Now is the winter of our discontent. diff --git a/ext/openssl/tests/openssl_cms_encrypt_basic.phpt b/ext/openssl/tests/openssl_cms_encrypt_basic.phpt index 14b5231fdd3..0ddda76d83a 100644 --- a/ext/openssl/tests/openssl_cms_encrypt_basic.phpt +++ b/ext/openssl/tests/openssl_cms_encrypt_basic.phpt @@ -5,13 +5,9 @@ openssl --FILE-- +--CLEAN-- + --EXPECT-- bool(true) bool(true) diff --git a/ext/openssl/tests/openssl_encrypt_cbc.phpt b/ext/openssl/tests/openssl_encrypt_cbc.phpt new file mode 100644 index 00000000000..5ac526afaa0 --- /dev/null +++ b/ext/openssl/tests/openssl_encrypt_cbc.phpt @@ -0,0 +1,12 @@ +--TEST-- +openssl_encrypt() CBC and its alias +--EXTENSIONS-- +openssl +--FILE-- + +--EXPECTF-- +string(48) "7a654459353452676f6c6b6a446b75455a6c4c6b4f513d3d" +string(48) "7a654459353452676f6c6b6a446b75455a6c4c6b4f513d3d" diff --git a/ext/openssl/tests/openssl_libctx_with_zts_argon.phpt b/ext/openssl/tests/openssl_libctx_with_zts_argon.phpt new file mode 100644 index 00000000000..13efcaa26b6 --- /dev/null +++ b/ext/openssl/tests/openssl_libctx_with_zts_argon.phpt @@ -0,0 +1,22 @@ +--TEST-- +openssl.libctx INI setting when Argon2 enabled and ZTS used +--EXTENSIONS-- +openssl +--INI-- +openssl.libctx = default +--SKIPIF-- + +--FILE-- + +--EXPECT-- +Fatal error: PHP Startup: OpenSSL libctx "default" cannot be used in this configuration in Unknown on line 0 +string(6) "custom" diff --git a/ext/openssl/tests/openssl_libctx_without_zts_argon.phpt b/ext/openssl/tests/openssl_libctx_without_zts_argon.phpt new file mode 100644 index 00000000000..f2fd64b7469 --- /dev/null +++ b/ext/openssl/tests/openssl_libctx_without_zts_argon.phpt @@ -0,0 +1,18 @@ +--TEST-- +openssl.libctx INI setting when Argon2 disable or ZTS not used +--EXTENSIONS-- +openssl +--INI-- +openssl.libctx = default +--SKIPIF-- + +--FILE-- + +--EXPECT-- +string(7) "default" diff --git a/ext/openssl/tests/openssl_pkey_derive_deprecated_key_length_param.phpt b/ext/openssl/tests/openssl_pkey_derive_deprecated_key_length_param.phpt new file mode 100644 index 00000000000..b6a4c916753 --- /dev/null +++ b/ext/openssl/tests/openssl_pkey_derive_deprecated_key_length_param.phpt @@ -0,0 +1,45 @@ +--TEST-- +openssl_pkey_derive() DH +--EXTENSIONS-- +openssl +--FILE-- + +--EXPECTF-- +Deprecated: openssl_pkey_derive(): the $key_length parameter is deprecated as it is either ignored or truncates the key in %s on line %d +string(512) "10aed66ad96a65f50543aa9adbc18ea169bf98521c682c49fb8b7daeb9e8fbe6b9a800199ffe1123cc36fc358829cbbc5d21bf1eb8ce3cf644538b357f478361a284c27fbe31fc94d431562786dd7314613cd70e6d76ca1ab3c1f31556ed07162f243dcc1a43ea98c454fb6e891eaec7a14158d54cd33d3fbbbc75f1ea8ff5deaab25d5deb657c7c43004252df301b195207d01614e7cb833e0e8d785ba2ecfe16ad7a9634784fdb8db8afe049476b58743575725ee99c761a59a7d7b9e709fff84c8d427e2bc07953a7c2408eb3f8f7e0ebc2f901c6889955874ae79a3de19921757d69424145a35dbe5af778b080dada55bdfce8fb0319f2de39110f58e05d" diff --git a/ext/openssl/tests/openssl_private_decrypt_digest.phpt b/ext/openssl/tests/openssl_private_decrypt_digest.phpt new file mode 100644 index 00000000000..9bb07ba71ea --- /dev/null +++ b/ext/openssl/tests/openssl_private_decrypt_digest.phpt @@ -0,0 +1,57 @@ +--TEST-- +openssl_private_decrypt() with digest algorithm tests +--EXTENSIONS-- +openssl +--FILE-- +getMessage()); +} + +openssl_public_encrypt($data, $encrypted_pkcs1, $pubkey, OPENSSL_PKCS1_PADDING); +var_dump(openssl_private_decrypt($encrypted_pkcs1, $output_pkcs1, $privkey, OPENSSL_PKCS1_PADDING, "sha256")); +var_dump($output_pkcs1); +?> +--EXPECTF-- +bool(true) +string(56) "Testing openssl_private_decrypt() with digest algorithms" +bool(true) +string(56) "Testing openssl_private_decrypt() with digest algorithms" +bool(false) +NULL + +Warning: openssl_private_decrypt(): Unknown digest algorithm: invalid_hash in %s on line %d +bool(false) +NULL +string(85) "openssl_private_decrypt(): Argument #5 ($digest_algo) must not contain any null bytes" +bool(true) +string(56) "Testing openssl_private_decrypt() with digest algorithms" diff --git a/ext/openssl/tests/openssl_sign_basic.phpt b/ext/openssl/tests/openssl_sign_basic.phpt index 04702810189..9d2edbec59f 100644 --- a/ext/openssl/tests/openssl_sign_basic.phpt +++ b/ext/openssl/tests/openssl_sign_basic.phpt @@ -8,11 +8,27 @@ $data = "Testing openssl_sign()"; $privkey = "file://" . __DIR__ . "/private_rsa_1024.key"; $wrong = "wrong"; -var_dump(openssl_sign($data, $sign, $privkey, OPENSSL_ALGO_SHA256)); // no output +var_dump(openssl_sign($data, $sign1, $privkey, OPENSSL_ALGO_SHA256)); +var_dump(bin2hex($sign1)); +var_dump(openssl_sign($data, $sign2, $privkey, OPENSSL_ALGO_SHA256)); +var_dump($sign1 === $sign2); +var_dump(openssl_sign($data, $sign1, $privkey, OPENSSL_ALGO_SHA256, OPENSSL_PKCS1_PSS_PADDING)); +var_dump(strlen($sign1)); +var_dump(openssl_sign($data, $sign2, $privkey, OPENSSL_ALGO_SHA256, OPENSSL_PKCS1_PSS_PADDING)); +var_dump(strlen($sign2)); +var_dump($sign1 === $sign2); var_dump(openssl_sign($data, $sign, $wrong)); ?> --EXPECTF-- bool(true) +string(256) "5eff033d92208fcbf52edc9cbf6c9d4bd7c06b7b5a6a22c7d641d1494a09d6b0898d321c0a8fdb55c10b9bf25c2bb777c2b4660f867001f79879d089de7321a28df5f037cc02b68c47d1eb28d98a9199876961adb02524a489872a12fd3675db6a957d623ff04b9f715b565f516806cea247264c82a7569871dbd0b86cfe4689" +bool(true) +bool(true) +bool(true) +int(128) +bool(true) +int(128) +bool(false) Warning: openssl_sign(): Supplied key param cannot be coerced into a private key in %s on line %d bool(false) diff --git a/ext/openssl/tests/openssl_verify_basic.phpt b/ext/openssl/tests/openssl_verify_basic.phpt index 674a3c58a9e..1b28c137108 100644 --- a/ext/openssl/tests/openssl_verify_basic.phpt +++ b/ext/openssl/tests/openssl_verify_basic.phpt @@ -9,6 +9,10 @@ $privkey = "file://" . __DIR__ . "/private_rsa_1024.key"; $pubkey = "file://" . __DIR__ . "/public.key"; $wrong = "wrong"; + +openssl_sign($data, $sign, $privkey, OPENSSL_ALGO_SHA256, OPENSSL_PKCS1_PSS_PADDING); +var_dump(openssl_verify($data, $sign, $pubkey, OPENSSL_ALGO_SHA256, OPENSSL_PKCS1_PSS_PADDING)); +var_dump(openssl_verify($data, $sign, $pubkey, OPENSSL_ALGO_SHA256)); openssl_sign($data, $sign, $privkey, OPENSSL_ALGO_SHA256); var_dump(openssl_verify($data, $sign, $pubkey, OPENSSL_ALGO_SHA256)); var_dump(openssl_verify($data, $sign, $privkey, OPENSSL_ALGO_SHA256)); @@ -18,6 +22,8 @@ var_dump(openssl_verify($wrong, $sign, $pubkey, OPENSSL_ALGO_SHA256)); ?> --EXPECTF-- int(1) +int(0) +int(1) Warning: openssl_verify(): Supplied key param cannot be coerced into a public key in %s on line %d bool(false) diff --git a/ext/openssl/xp_ssl.c b/ext/openssl/xp_ssl.c index d53e55aa155..c1db5a78369 100644 --- a/ext/openssl/xp_ssl.c +++ b/ext/openssl/xp_ssl.c @@ -27,6 +27,7 @@ #include "streams/php_streams_int.h" #include "zend_smart_str.h" #include "php_openssl.h" +#include "php_openssl_backend.h" #include "php_network.h" #include #include @@ -237,7 +238,7 @@ static int php_openssl_handle_ssl_error(php_stream *stream, int nr_bytes, bool i char esbuf[512]; smart_str ebuf = {0}; unsigned long ecode; - int retry = 1; + bool retry = true; switch(err) { case SSL_ERROR_ZERO_RETURN: @@ -249,7 +250,7 @@ static int php_openssl_handle_ssl_error(php_stream *stream, int nr_bytes, bool i /* re-negotiation, or perhaps the SSL layer needs more * packets: retry in next iteration */ errno = EAGAIN; - retry = is_init ? 1 : sslsock->s.is_blocked; + retry = is_init ? true : sslsock->s.is_blocked; break; case SSL_ERROR_SYSCALL: if (ERR_peek_error() == 0) { @@ -850,7 +851,7 @@ static long php_openssl_load_stream_cafile(X509_STORE *cert_store, const char *c add_cert: { BIO_puts(buffer, line); efree(line); - cert = PEM_read_bio_X509(buffer, NULL, 0, NULL); + cert = php_openssl_pem_read_bio_x509(buffer); BIO_free(buffer); buffer_active = 0; if (cert && X509_STORE_add_cert(cert_store, cert)) { @@ -1806,7 +1807,7 @@ static int php_openssl_enable_crypto(php_stream *stream, if (cparam->inputs.activate && !sslsock->ssl_active) { struct timeval start_time, *timeout; - int blocked = sslsock->s.is_blocked, has_timeout = 0; + bool blocked = sslsock->s.is_blocked, has_timeout = false; #ifdef HAVE_TLS_SNI if (sslsock->is_client) { @@ -1946,8 +1947,8 @@ static ssize_t php_openssl_sockop_io(int read, php_stream *stream, char *buf, si int retry = 1; struct timeval start_time; struct timeval *timeout = NULL; - int began_blocked = sslsock->s.is_blocked; - int has_timeout = 0; + bool began_blocked = sslsock->s.is_blocked; + bool has_timeout = false; int nr_bytes = 0; /* prevent overflow in openssl */ @@ -1965,7 +1966,7 @@ static ssize_t php_openssl_sockop_io(int read, php_stream *stream, char *buf, si } if (!sslsock->s.is_blocked && timeout && (timeout->tv_sec > 0 || (timeout->tv_sec == 0 && timeout->tv_usec))) { - has_timeout = 1; + has_timeout = true; /* gettimeofday is not monotonic; using it here is not strictly correct */ gettimeofday(&start_time, NULL); } @@ -1987,7 +1988,7 @@ static ssize_t php_openssl_sockop_io(int read, php_stream *stream, char *buf, si if (began_blocked) { php_openssl_set_blocking(sslsock, 1); } - sslsock->s.timeout_event = 1; + sslsock->s.timeout_event = true; return -1; } } @@ -2248,7 +2249,7 @@ static inline int php_openssl_tcp_sockop_accept(php_stream *stream, php_openssl_ clisockdata->s.socket = clisock; #ifdef __linux__ /* O_NONBLOCK is not inherited on Linux */ - clisockdata->s.is_blocked = 1; + clisockdata->s.is_blocked = true; #endif xparam->outputs.client = php_stream_alloc_rel(stream->ops, clisockdata, NULL, "r+"); @@ -2273,6 +2274,12 @@ static inline int php_openssl_tcp_sockop_accept(php_stream *stream, php_openssl_ php_stream_close(xparam->outputs.client); xparam->outputs.client = NULL; xparam->outputs.returncode = -1; + if (xparam->want_errortext) { + if (xparam->outputs.error_text) { + zend_string_free(xparam->outputs.error_text); + } + xparam->outputs.error_text = ZSTR_INIT_LITERAL("Cannot enable crypto", 0); + } } } } @@ -2379,8 +2386,8 @@ static int php_openssl_sockop_set_option(php_stream *stream, int option, int val int retry = 1; struct timeval start_time; struct timeval *timeout = NULL; - int began_blocked = sslsock->s.is_blocked; - int has_timeout = 0; + bool began_blocked = sslsock->s.is_blocked; + bool has_timeout = false; /* never use a timeout with non-blocking sockets */ if (began_blocked) { @@ -2392,7 +2399,7 @@ static int php_openssl_sockop_set_option(php_stream *stream, int option, int val } if (!sslsock->s.is_blocked && timeout && (timeout->tv_sec > 0 || (timeout->tv_sec == 0 && timeout->tv_usec))) { - has_timeout = 1; + has_timeout = true; /* gettimeofday is not monotonic; using it here is not strictly correct */ gettimeofday(&start_time, NULL); } @@ -2414,7 +2421,7 @@ static int php_openssl_sockop_set_option(php_stream *stream, int option, int val if (began_blocked) { php_openssl_set_blocking(sslsock, 1); } - sslsock->s.timeout_event = 1; + sslsock->s.timeout_event = true; return PHP_STREAM_OPTION_RETURN_ERR; } } @@ -2438,7 +2445,7 @@ static int php_openssl_sockop_set_option(php_stream *stream, int option, int val } /* Don't loop indefinitely in non-blocking mode if no data is available */ - if (began_blocked == 0 || !has_timeout) { + if (!began_blocked || !has_timeout) { alive = retry; break; } @@ -2668,7 +2675,7 @@ php_stream *php_openssl_ssl_socket_factory(const char *proto, size_t protolen, sslsock = pemalloc(sizeof(php_openssl_netstream_data_t), persistent_id ? 1 : 0); memset(sslsock, 0, sizeof(*sslsock)); - sslsock->s.is_blocked = 1; + sslsock->s.is_blocked = true; /* this timeout is used by standard stream funcs, therefore it should use the default value */ #ifdef _WIN32 sslsock->s.timeout.tv_sec = (long)FG(default_socket_timeout); diff --git a/ext/pcntl/pcntl.c b/ext/pcntl/pcntl.c index e11de304b1b..4d1b5dff2e3 100644 --- a/ext/pcntl/pcntl.c +++ b/ext/pcntl/pcntl.c @@ -32,6 +32,7 @@ #include "php_signal.h" #include "php_ticks.h" #include "zend_fibers.h" +#include "main/php_main.h" #if defined(HAVE_GETPRIORITY) || defined(HAVE_SETPRIORITY) || defined(HAVE_WAIT3) #include @@ -297,7 +298,7 @@ PHP_FUNCTION(pcntl_fork) } } else if (id == 0) { - zend_max_execution_timer_init(); + php_child_init(); } RETURN_LONG((zend_long) id); @@ -1560,7 +1561,7 @@ PHP_FUNCTION(pcntl_rfork) php_error_docref(NULL, E_WARNING, "Error %d", errno); } } else if (pid == 0) { - zend_max_execution_timer_init(); + php_child_init(); } RETURN_LONG((zend_long) pid); @@ -1605,7 +1606,7 @@ PHP_FUNCTION(pcntl_forkx) php_error_docref(NULL, E_WARNING, "Error %d", errno); } } else if (pid == 0) { - zend_max_execution_timer_init(); + php_child_init(); } RETURN_LONG((zend_long) pid); diff --git a/ext/pcre/config0.m4 b/ext/pcre/config0.m4 index d049cc538c0..4682080e030 100644 --- a/ext/pcre/config0.m4 +++ b/ext/pcre/config0.m4 @@ -96,8 +96,7 @@ else "]) AX_CHECK_COMPILE_FLAG([-Wno-implicit-fallthrough], - [PHP_PCRE_CFLAGS="$PHP_PCRE_CFLAGS -Wno-implicit-fallthrough"],, - [-Werror]) + [PHP_PCRE_CFLAGS="$PHP_PCRE_CFLAGS -Wno-implicit-fallthrough"]) PHP_PCRE_CFLAGS=m4_normalize([" $PHP_PCRE_CFLAGS diff --git a/ext/pdo/pdo_dbh.c b/ext/pdo/pdo_dbh.c index 9588f23d420..af8149322f2 100644 --- a/ext/pdo/pdo_dbh.c +++ b/ext/pdo/pdo_dbh.c @@ -347,6 +347,11 @@ PDO_API void php_pdo_internal_construct_driver(INTERNAL_FUNCTION_PARAMETERS, zen } if (!strncmp(data_source, "uri:", sizeof("uri:")-1)) { + zend_error(E_DEPRECATED, "Looking up the DSN from a URI is deprecated due to possible security concerns with DSNs coming from remote URIs"); + if (EG(exception)) { + RETURN_THROWS(); + } + /* the specified URI holds connection details */ data_source = dsn_from_uri(data_source + sizeof("uri:")-1, alt_dsn, sizeof(alt_dsn)); if (!data_source) { diff --git a/ext/pdo_mysql/php_pdo_mysql_int.h b/ext/pdo_mysql/php_pdo_mysql_int.h index ae77193afcf..ec49d6c311c 100644 --- a/ext/pdo_mysql/php_pdo_mysql_int.h +++ b/ext/pdo_mysql/php_pdo_mysql_int.h @@ -78,7 +78,7 @@ ZEND_BEGIN_MODULE_GLOBALS(pdo_mysql) /* dummy member so we get at least one member in the struct * and avoids build errors. */ - void *dummymemmber; + void *dummymember; #endif ZEND_END_MODULE_GLOBALS(pdo_mysql) diff --git a/ext/pdo_mysql/tests/pdo_mysql___construct_uri.phpt b/ext/pdo_mysql/tests/pdo_mysql___construct_uri.phpt index ec6bce78b7c..d86f9b3d877 100644 --- a/ext/pdo_mysql/tests/pdo_mysql___construct_uri.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql___construct_uri.phpt @@ -63,5 +63,8 @@ MySQLPDOTest::skip(); print "done!"; ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Looking up the DSN from a URI is deprecated due to possible security concerns with DSNs coming from remote URIs in %s on line %d + +Deprecated: Looking up the DSN from a URI is deprecated due to possible security concerns with DSNs coming from remote URIs in %s on line %d done! diff --git a/ext/pdo_mysql/tests/pdo_mysql_types.phpt b/ext/pdo_mysql/tests/pdo_mysql_types.phpt index 462a542c24c..7c7926a8cb9 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_types.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_types.phpt @@ -105,7 +105,7 @@ MySQLPDOTest::skip(); test_type($db, 90, 'MEDIUMINT UNSIGNED', 16777215, ($is_mysqlnd) ? 16777215 : '16777215'); test_type($db, 100, 'INT', -2147483648, - ($is_mysqlnd) ? ((PHP_INT_SIZE > 4) ? (int)-2147483648 : (double)-2147483648) : '-2147483648', + ($is_mysqlnd) ? ((PHP_INT_SIZE > 4) ? (int)-2147483648 : (float)-2147483648) : '-2147483648', NULL, ($is_mysqlnd) ? 'integer' : NULL); test_type($db, 110, 'INT UNSIGNED', 4294967295, ($is_mysqlnd) ? ((PHP_INT_SIZE > 4) ? 4294967295 : '4294967295') : '4294967295'); diff --git a/ext/pdo_pgsql/pgsql_driver.c b/ext/pdo_pgsql/pgsql_driver.c index 35b86a3588f..be865c1f868 100644 --- a/ext/pdo_pgsql/pgsql_driver.c +++ b/ext/pdo_pgsql/pgsql_driver.c @@ -39,8 +39,14 @@ static bool pgsql_handle_in_transaction(pdo_dbh_t *dbh); static char * _pdo_pgsql_trim_message(const char *message, int persistent) { - size_t i = strlen(message)-1; + size_t i = strlen(message); char *tmp; + if (UNEXPECTED(i == 0)) { + tmp = pemalloc(1, persistent); + tmp[0] = '\0'; + return tmp; + } + --i; if (i>1 && (message[i-1] == '\r' || message[i-1] == '\n') && message[i] == '.') { --i; diff --git a/ext/pdo_pgsql/pgsql_statement.c b/ext/pdo_pgsql/pgsql_statement.c index 3485bd8df00..f9320fd86ea 100644 --- a/ext/pdo_pgsql/pgsql_statement.c +++ b/ext/pdo_pgsql/pgsql_statement.c @@ -526,10 +526,10 @@ static int pgsql_stmt_fetch(pdo_stmt_t *stmt, ExecStatusType status; switch (ori) { - case PDO_FETCH_ORI_NEXT: spprintf(&ori_str, 0, "NEXT"); break; - case PDO_FETCH_ORI_PRIOR: spprintf(&ori_str, 0, "BACKWARD"); break; - case PDO_FETCH_ORI_FIRST: spprintf(&ori_str, 0, "FIRST"); break; - case PDO_FETCH_ORI_LAST: spprintf(&ori_str, 0, "LAST"); break; + case PDO_FETCH_ORI_NEXT: ori_str = "NEXT"; break; + case PDO_FETCH_ORI_PRIOR: ori_str = "BACKWARD"; break; + case PDO_FETCH_ORI_FIRST: ori_str = "FIRST"; break; + case PDO_FETCH_ORI_LAST: ori_str = "LAST"; break; case PDO_FETCH_ORI_ABS: spprintf(&ori_str, 0, "ABSOLUTE " ZEND_LONG_FMT, offset); break; case PDO_FETCH_ORI_REL: spprintf(&ori_str, 0, "RELATIVE " ZEND_LONG_FMT, offset); break; default: @@ -542,7 +542,9 @@ static int pgsql_stmt_fetch(pdo_stmt_t *stmt, } spprintf(&q, 0, "FETCH %s FROM %s", ori_str, S->cursor_name); - efree(ori_str); + if (ori == PDO_FETCH_ORI_ABS || ori == PDO_FETCH_ORI_REL) { + efree(ori_str); + } S->result = PQexec(S->H->server, q); efree(q); status = PQresultStatus(S->result); diff --git a/ext/pdo_sqlite/tests/pdo_sqlite___construct_uri.phpt b/ext/pdo_sqlite/tests/pdo_sqlite___construct_uri.phpt new file mode 100644 index 00000000000..7fc686b2147 --- /dev/null +++ b/ext/pdo_sqlite/tests/pdo_sqlite___construct_uri.phpt @@ -0,0 +1,48 @@ +--TEST-- +PDO_sqlite: PDO->__construct() - URI +--EXTENSIONS-- +pdo_sqlite +--FILE-- +getMessage(), PHP_EOL; +} + +clearstatcache(); +var_dump(file_exists($dbFile)); + +?> +--CLEAN-- + +--EXPECTF-- +bool(false) + +Deprecated: Looking up the DSN from a URI is deprecated due to possible security concerns with DSNs coming from remote URIs in %s on line %d +bool(true) +bool(false) +ErrorException: Looking up the DSN from a URI is deprecated due to possible security concerns with DSNs coming from remote URIs +bool(false) diff --git a/ext/pgsql/pgsql.c b/ext/pgsql/pgsql.c index 3d180e3d6b9..d97d0faa1a4 100644 --- a/ext/pgsql/pgsql.c +++ b/ext/pgsql/pgsql.c @@ -321,6 +321,10 @@ static void _close_pgsql_plink(zend_resource *rsrc) static void _php_pgsql_notice_handler(void *l, const char *message) { + if (l == NULL) { + /* This connection does not currently have a valid context, ignore this notice */ + return; + } if (PGG(ignore_notices)) { return; } @@ -353,6 +357,11 @@ static int _rollback_transactions(zval *el) link = (PGconn *) rsrc->ptr; + /* unset notice processor if we initially did set it */ + if (PQsetNoticeProcessor(link, NULL, NULL) == _php_pgsql_notice_handler) { + PQsetNoticeProcessor(link, _php_pgsql_notice_handler, NULL); + } + if (PQsetnonblocking(link, 0)) { php_error_docref("ref.pgsql", E_NOTICE, "Cannot set connection to blocking mode"); return -1; @@ -6253,7 +6262,6 @@ PHP_FUNCTION(pg_select) PGconn *pg_link; zend_string *sql = NULL; - /* TODO Document result_type param on php.net (apparently it was added in PHP 7.1) */ ZEND_PARSE_PARAMETERS_START(2, 5) Z_PARAM_OBJECT_OF_CLASS(pgsql_link, pgsql_link_ce) Z_PARAM_PATH_STR(table) @@ -6389,7 +6397,7 @@ PHP_FUNCTION(pg_socket_poll) Z_PARAM_LONG(ts) ZEND_PARSE_PARAMETERS_END(); - if (php_stream_cast(stream, PHP_STREAM_AS_SOCKETD, (void **)&socket, 0)) { + if (UNEXPECTED(php_stream_cast(stream, PHP_STREAM_AS_SOCKETD, (void **)&socket, 0) == FAILURE)) { zend_argument_type_error(1, "invalid resource socket"); RETURN_THROWS(); } diff --git a/ext/pgsql/pgsql_arginfo.h b/ext/pgsql/pgsql_arginfo.h index 9bec05ff4c3..2d9eec94435 100644 --- a/ext/pgsql/pgsql_arginfo.h +++ b/ext/pgsql/pgsql_arginfo.h @@ -867,217 +867,169 @@ static void register_pgsql_symbols(int module_number) zend_attribute *attribute_Deprecated_func_pg_errormessage_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "pg_errormessage", sizeof("pg_errormessage") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_func_pg_errormessage_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_func_pg_errormessage_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_pg_errormessage_0_arg1; zend_string *attribute_Deprecated_func_pg_errormessage_0_arg1_str = zend_string_init("use pg_last_error() instead", strlen("use pg_last_error() instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_pg_errormessage_0_arg1, attribute_Deprecated_func_pg_errormessage_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_pg_errormessage_0->args[1].value, &attribute_Deprecated_func_pg_errormessage_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_pg_errormessage_0->args[1].value, attribute_Deprecated_func_pg_errormessage_0_arg1_str); attribute_Deprecated_func_pg_errormessage_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_func_pg_numrows_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "pg_numrows", sizeof("pg_numrows") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_func_pg_numrows_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_func_pg_numrows_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_pg_numrows_0_arg1; zend_string *attribute_Deprecated_func_pg_numrows_0_arg1_str = zend_string_init("use pg_num_rows() instead", strlen("use pg_num_rows() instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_pg_numrows_0_arg1, attribute_Deprecated_func_pg_numrows_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_pg_numrows_0->args[1].value, &attribute_Deprecated_func_pg_numrows_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_pg_numrows_0->args[1].value, attribute_Deprecated_func_pg_numrows_0_arg1_str); attribute_Deprecated_func_pg_numrows_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_func_pg_numfields_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "pg_numfields", sizeof("pg_numfields") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_func_pg_numfields_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_func_pg_numfields_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_pg_numfields_0_arg1; zend_string *attribute_Deprecated_func_pg_numfields_0_arg1_str = zend_string_init("use pg_num_fields() instead", strlen("use pg_num_fields() instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_pg_numfields_0_arg1, attribute_Deprecated_func_pg_numfields_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_pg_numfields_0->args[1].value, &attribute_Deprecated_func_pg_numfields_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_pg_numfields_0->args[1].value, attribute_Deprecated_func_pg_numfields_0_arg1_str); attribute_Deprecated_func_pg_numfields_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_func_pg_cmdtuples_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "pg_cmdtuples", sizeof("pg_cmdtuples") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_func_pg_cmdtuples_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_func_pg_cmdtuples_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_pg_cmdtuples_0_arg1; zend_string *attribute_Deprecated_func_pg_cmdtuples_0_arg1_str = zend_string_init("use pg_affected_rows() instead", strlen("use pg_affected_rows() instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_pg_cmdtuples_0_arg1, attribute_Deprecated_func_pg_cmdtuples_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_pg_cmdtuples_0->args[1].value, &attribute_Deprecated_func_pg_cmdtuples_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_pg_cmdtuples_0->args[1].value, attribute_Deprecated_func_pg_cmdtuples_0_arg1_str); attribute_Deprecated_func_pg_cmdtuples_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_func_pg_fieldname_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "pg_fieldname", sizeof("pg_fieldname") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_func_pg_fieldname_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_func_pg_fieldname_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_pg_fieldname_0_arg1; zend_string *attribute_Deprecated_func_pg_fieldname_0_arg1_str = zend_string_init("use pg_field_name() instead", strlen("use pg_field_name() instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_pg_fieldname_0_arg1, attribute_Deprecated_func_pg_fieldname_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_pg_fieldname_0->args[1].value, &attribute_Deprecated_func_pg_fieldname_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_pg_fieldname_0->args[1].value, attribute_Deprecated_func_pg_fieldname_0_arg1_str); attribute_Deprecated_func_pg_fieldname_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_func_pg_fieldsize_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "pg_fieldsize", sizeof("pg_fieldsize") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_func_pg_fieldsize_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_func_pg_fieldsize_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_pg_fieldsize_0_arg1; zend_string *attribute_Deprecated_func_pg_fieldsize_0_arg1_str = zend_string_init("use pg_field_size() instead", strlen("use pg_field_size() instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_pg_fieldsize_0_arg1, attribute_Deprecated_func_pg_fieldsize_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_pg_fieldsize_0->args[1].value, &attribute_Deprecated_func_pg_fieldsize_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_pg_fieldsize_0->args[1].value, attribute_Deprecated_func_pg_fieldsize_0_arg1_str); attribute_Deprecated_func_pg_fieldsize_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_func_pg_fieldtype_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "pg_fieldtype", sizeof("pg_fieldtype") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_func_pg_fieldtype_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_func_pg_fieldtype_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_pg_fieldtype_0_arg1; zend_string *attribute_Deprecated_func_pg_fieldtype_0_arg1_str = zend_string_init("use pg_field_type() instead", strlen("use pg_field_type() instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_pg_fieldtype_0_arg1, attribute_Deprecated_func_pg_fieldtype_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_pg_fieldtype_0->args[1].value, &attribute_Deprecated_func_pg_fieldtype_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_pg_fieldtype_0->args[1].value, attribute_Deprecated_func_pg_fieldtype_0_arg1_str); attribute_Deprecated_func_pg_fieldtype_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_func_pg_fieldnum_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "pg_fieldnum", sizeof("pg_fieldnum") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_func_pg_fieldnum_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_func_pg_fieldnum_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_pg_fieldnum_0_arg1; zend_string *attribute_Deprecated_func_pg_fieldnum_0_arg1_str = zend_string_init("use pg_field_num() instead", strlen("use pg_field_num() instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_pg_fieldnum_0_arg1, attribute_Deprecated_func_pg_fieldnum_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_pg_fieldnum_0->args[1].value, &attribute_Deprecated_func_pg_fieldnum_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_pg_fieldnum_0->args[1].value, attribute_Deprecated_func_pg_fieldnum_0_arg1_str); attribute_Deprecated_func_pg_fieldnum_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_func_pg_result_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "pg_result", sizeof("pg_result") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_func_pg_result_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_func_pg_result_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_pg_result_0_arg1; zend_string *attribute_Deprecated_func_pg_result_0_arg1_str = zend_string_init("use pg_fetch_result() instead", strlen("use pg_fetch_result() instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_pg_result_0_arg1, attribute_Deprecated_func_pg_result_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_pg_result_0->args[1].value, &attribute_Deprecated_func_pg_result_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_pg_result_0->args[1].value, attribute_Deprecated_func_pg_result_0_arg1_str); attribute_Deprecated_func_pg_result_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_func_pg_fieldprtlen_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "pg_fieldprtlen", sizeof("pg_fieldprtlen") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_func_pg_fieldprtlen_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_func_pg_fieldprtlen_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_pg_fieldprtlen_0_arg1; zend_string *attribute_Deprecated_func_pg_fieldprtlen_0_arg1_str = zend_string_init("use pg_field_prtlen() instead", strlen("use pg_field_prtlen() instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_pg_fieldprtlen_0_arg1, attribute_Deprecated_func_pg_fieldprtlen_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_pg_fieldprtlen_0->args[1].value, &attribute_Deprecated_func_pg_fieldprtlen_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_pg_fieldprtlen_0->args[1].value, attribute_Deprecated_func_pg_fieldprtlen_0_arg1_str); attribute_Deprecated_func_pg_fieldprtlen_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_func_pg_fieldisnull_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "pg_fieldisnull", sizeof("pg_fieldisnull") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_func_pg_fieldisnull_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_func_pg_fieldisnull_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_pg_fieldisnull_0_arg1; zend_string *attribute_Deprecated_func_pg_fieldisnull_0_arg1_str = zend_string_init("use pg_field_is_null() instead", strlen("use pg_field_is_null() instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_pg_fieldisnull_0_arg1, attribute_Deprecated_func_pg_fieldisnull_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_pg_fieldisnull_0->args[1].value, &attribute_Deprecated_func_pg_fieldisnull_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_pg_fieldisnull_0->args[1].value, attribute_Deprecated_func_pg_fieldisnull_0_arg1_str); attribute_Deprecated_func_pg_fieldisnull_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_func_pg_freeresult_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "pg_freeresult", sizeof("pg_freeresult") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_func_pg_freeresult_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_func_pg_freeresult_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_pg_freeresult_0_arg1; zend_string *attribute_Deprecated_func_pg_freeresult_0_arg1_str = zend_string_init("use pg_free_result() instead", strlen("use pg_free_result() instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_pg_freeresult_0_arg1, attribute_Deprecated_func_pg_freeresult_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_pg_freeresult_0->args[1].value, &attribute_Deprecated_func_pg_freeresult_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_pg_freeresult_0->args[1].value, attribute_Deprecated_func_pg_freeresult_0_arg1_str); attribute_Deprecated_func_pg_freeresult_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_func_pg_getlastoid_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "pg_getlastoid", sizeof("pg_getlastoid") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_func_pg_getlastoid_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_func_pg_getlastoid_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_pg_getlastoid_0_arg1; zend_string *attribute_Deprecated_func_pg_getlastoid_0_arg1_str = zend_string_init("use pg_last_oid() instead", strlen("use pg_last_oid() instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_pg_getlastoid_0_arg1, attribute_Deprecated_func_pg_getlastoid_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_pg_getlastoid_0->args[1].value, &attribute_Deprecated_func_pg_getlastoid_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_pg_getlastoid_0->args[1].value, attribute_Deprecated_func_pg_getlastoid_0_arg1_str); attribute_Deprecated_func_pg_getlastoid_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_func_pg_locreate_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "pg_locreate", sizeof("pg_locreate") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_func_pg_locreate_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_func_pg_locreate_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_pg_locreate_0_arg1; zend_string *attribute_Deprecated_func_pg_locreate_0_arg1_str = zend_string_init("use pg_lo_create() instead", strlen("use pg_lo_create() instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_pg_locreate_0_arg1, attribute_Deprecated_func_pg_locreate_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_pg_locreate_0->args[1].value, &attribute_Deprecated_func_pg_locreate_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_pg_locreate_0->args[1].value, attribute_Deprecated_func_pg_locreate_0_arg1_str); attribute_Deprecated_func_pg_locreate_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_func_pg_lounlink_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "pg_lounlink", sizeof("pg_lounlink") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_func_pg_lounlink_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_func_pg_lounlink_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_pg_lounlink_0_arg1; zend_string *attribute_Deprecated_func_pg_lounlink_0_arg1_str = zend_string_init("use pg_lo_unlink() instead", strlen("use pg_lo_unlink() instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_pg_lounlink_0_arg1, attribute_Deprecated_func_pg_lounlink_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_pg_lounlink_0->args[1].value, &attribute_Deprecated_func_pg_lounlink_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_pg_lounlink_0->args[1].value, attribute_Deprecated_func_pg_lounlink_0_arg1_str); attribute_Deprecated_func_pg_lounlink_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_func_pg_loopen_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "pg_loopen", sizeof("pg_loopen") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_func_pg_loopen_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_func_pg_loopen_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_pg_loopen_0_arg1; zend_string *attribute_Deprecated_func_pg_loopen_0_arg1_str = zend_string_init("use pg_lo_open() instead", strlen("use pg_lo_open() instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_pg_loopen_0_arg1, attribute_Deprecated_func_pg_loopen_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_pg_loopen_0->args[1].value, &attribute_Deprecated_func_pg_loopen_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_pg_loopen_0->args[1].value, attribute_Deprecated_func_pg_loopen_0_arg1_str); attribute_Deprecated_func_pg_loopen_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_func_pg_loclose_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "pg_loclose", sizeof("pg_loclose") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_func_pg_loclose_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_func_pg_loclose_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_pg_loclose_0_arg1; zend_string *attribute_Deprecated_func_pg_loclose_0_arg1_str = zend_string_init("use pg_lo_close() instead", strlen("use pg_lo_close() instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_pg_loclose_0_arg1, attribute_Deprecated_func_pg_loclose_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_pg_loclose_0->args[1].value, &attribute_Deprecated_func_pg_loclose_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_pg_loclose_0->args[1].value, attribute_Deprecated_func_pg_loclose_0_arg1_str); attribute_Deprecated_func_pg_loclose_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_func_pg_loread_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "pg_loread", sizeof("pg_loread") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_func_pg_loread_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_func_pg_loread_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_pg_loread_0_arg1; zend_string *attribute_Deprecated_func_pg_loread_0_arg1_str = zend_string_init("use pg_lo_read() instead", strlen("use pg_lo_read() instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_pg_loread_0_arg1, attribute_Deprecated_func_pg_loread_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_pg_loread_0->args[1].value, &attribute_Deprecated_func_pg_loread_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_pg_loread_0->args[1].value, attribute_Deprecated_func_pg_loread_0_arg1_str); attribute_Deprecated_func_pg_loread_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_func_pg_lowrite_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "pg_lowrite", sizeof("pg_lowrite") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_func_pg_lowrite_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_func_pg_lowrite_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_pg_lowrite_0_arg1; zend_string *attribute_Deprecated_func_pg_lowrite_0_arg1_str = zend_string_init("use pg_lo_write() instead", strlen("use pg_lo_write() instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_pg_lowrite_0_arg1, attribute_Deprecated_func_pg_lowrite_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_pg_lowrite_0->args[1].value, &attribute_Deprecated_func_pg_lowrite_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_pg_lowrite_0->args[1].value, attribute_Deprecated_func_pg_lowrite_0_arg1_str); attribute_Deprecated_func_pg_lowrite_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_func_pg_loreadall_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "pg_loreadall", sizeof("pg_loreadall") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_func_pg_loreadall_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_func_pg_loreadall_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_pg_loreadall_0_arg1; zend_string *attribute_Deprecated_func_pg_loreadall_0_arg1_str = zend_string_init("use pg_lo_read_all() instead", strlen("use pg_lo_read_all() instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_pg_loreadall_0_arg1, attribute_Deprecated_func_pg_loreadall_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_pg_loreadall_0->args[1].value, &attribute_Deprecated_func_pg_loreadall_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_pg_loreadall_0->args[1].value, attribute_Deprecated_func_pg_loreadall_0_arg1_str); attribute_Deprecated_func_pg_loreadall_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_func_pg_loimport_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "pg_loimport", sizeof("pg_loimport") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_func_pg_loimport_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_func_pg_loimport_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_pg_loimport_0_arg1; zend_string *attribute_Deprecated_func_pg_loimport_0_arg1_str = zend_string_init("use pg_lo_import() instead", strlen("use pg_lo_import() instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_pg_loimport_0_arg1, attribute_Deprecated_func_pg_loimport_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_pg_loimport_0->args[1].value, &attribute_Deprecated_func_pg_loimport_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_pg_loimport_0->args[1].value, attribute_Deprecated_func_pg_loimport_0_arg1_str); attribute_Deprecated_func_pg_loimport_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_func_pg_loexport_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "pg_loexport", sizeof("pg_loexport") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_func_pg_loexport_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_func_pg_loexport_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_pg_loexport_0_arg1; zend_string *attribute_Deprecated_func_pg_loexport_0_arg1_str = zend_string_init("use pg_lo_export() instead", strlen("use pg_lo_export() instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_pg_loexport_0_arg1, attribute_Deprecated_func_pg_loexport_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_pg_loexport_0->args[1].value, &attribute_Deprecated_func_pg_loexport_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_pg_loexport_0->args[1].value, attribute_Deprecated_func_pg_loexport_0_arg1_str); attribute_Deprecated_func_pg_loexport_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_func_pg_setclientencoding_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "pg_setclientencoding", sizeof("pg_setclientencoding") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_func_pg_setclientencoding_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_func_pg_setclientencoding_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_pg_setclientencoding_0_arg1; zend_string *attribute_Deprecated_func_pg_setclientencoding_0_arg1_str = zend_string_init("use pg_set_client_encoding() instead", strlen("use pg_set_client_encoding() instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_pg_setclientencoding_0_arg1, attribute_Deprecated_func_pg_setclientencoding_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_pg_setclientencoding_0->args[1].value, &attribute_Deprecated_func_pg_setclientencoding_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_pg_setclientencoding_0->args[1].value, attribute_Deprecated_func_pg_setclientencoding_0_arg1_str); attribute_Deprecated_func_pg_setclientencoding_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_func_pg_clientencoding_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "pg_clientencoding", sizeof("pg_clientencoding") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_func_pg_clientencoding_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_func_pg_clientencoding_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_pg_clientencoding_0_arg1; zend_string *attribute_Deprecated_func_pg_clientencoding_0_arg1_str = zend_string_init("use pg_client_encoding() instead", strlen("use pg_client_encoding() instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_pg_clientencoding_0_arg1, attribute_Deprecated_func_pg_clientencoding_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_pg_clientencoding_0->args[1].value, &attribute_Deprecated_func_pg_clientencoding_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_pg_clientencoding_0->args[1].value, attribute_Deprecated_func_pg_clientencoding_0_arg1_str); attribute_Deprecated_func_pg_clientencoding_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_add_parameter_attribute(zend_hash_str_find_ptr(CG(function_table), "pg_change_password", sizeof("pg_change_password") - 1), 2, ZSTR_KNOWN(ZEND_STR_SENSITIVEPARAMETER), 0); @@ -1085,10 +1037,8 @@ static void register_pgsql_symbols(int module_number) zend_attribute *attribute_Deprecated_const_PGSQL_LIBPQ_VERSION_STR_0 = zend_add_global_constant_attribute(const_PGSQL_LIBPQ_VERSION_STR, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_const_PGSQL_LIBPQ_VERSION_STR_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_const_PGSQL_LIBPQ_VERSION_STR_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_const_PGSQL_LIBPQ_VERSION_STR_0_arg1; zend_string *attribute_Deprecated_const_PGSQL_LIBPQ_VERSION_STR_0_arg1_str = zend_string_init("as it is the same as PGSQL_LIBPQ_VERSION", strlen("as it is the same as PGSQL_LIBPQ_VERSION"), 1); - ZVAL_STR(&attribute_Deprecated_const_PGSQL_LIBPQ_VERSION_STR_0_arg1, attribute_Deprecated_const_PGSQL_LIBPQ_VERSION_STR_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_const_PGSQL_LIBPQ_VERSION_STR_0->args[1].value, &attribute_Deprecated_const_PGSQL_LIBPQ_VERSION_STR_0_arg1); + ZVAL_STR(&attribute_Deprecated_const_PGSQL_LIBPQ_VERSION_STR_0->args[1].value, attribute_Deprecated_const_PGSQL_LIBPQ_VERSION_STR_0_arg1_str); attribute_Deprecated_const_PGSQL_LIBPQ_VERSION_STR_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); } diff --git a/ext/phar/phar/pharcommand.inc b/ext/phar/phar/pharcommand.inc index fee6c069ab0..7d35335a294 100644 --- a/ext/phar/phar/pharcommand.inc +++ b/ext/phar/phar/pharcommand.inc @@ -225,13 +225,13 @@ class PharCommand extends CLICommand } } if ($pear) { - $apiver = (string) `pear -q info PHP_Archive 2>/dev/null|grep 'API Version'`; + $apiver = (string) shell_exec("pear -q info PHP_Archive 2>/dev/null|grep 'API Version'"); $apiver = trim(substr($apiver, strlen('API Version'))); } if ($apiver) { self::notice("PEAR package PHP_Archive: API Version: $apiver.\n"); - $files = explode("\n", (string) `pear list-files PHP_Archive`); - $phpdir = (string) `pear config-get php_dir 2>/dev/null`; + $files = explode("\n", (string) shell_exec("pear list-files PHP_Archive")); + $phpdir = (string) shell_exec("pear config-get php_dir 2>/dev/null"); $phpdir = trim($phpdir); self::notice("PEAR package PHP_Archive: $phpdir.\n"); if (is_dir($phpdir)) { diff --git a/ext/phar/shortarc.php b/ext/phar/shortarc.php index 2d0d37d0dcc..0e88198a87a 100644 --- a/ext/phar/shortarc.php +++ b/ext/phar/shortarc.php @@ -114,15 +114,15 @@ class Extract_Phar { $fp = fopen(__FILE__, 'rb'); fseek($fp, self::LEN); - $L = unpack('V', $a = (binary)fread($fp, 4)); - $m = (binary)''; + $L = unpack('V', $a = (string)fread($fp, 4)); + $m = ''; do { $read = 8192; if ($L[1] - strlen($m) < 8192) { $read = $L[1] - strlen($m); } - $last = (binary)fread($fp, $read); + $last = (string)fread($fp, $read); $m .= $last; } while (strlen($last) && strlen($m) < $L[1]); @@ -268,7 +268,7 @@ class Extract_Phar $entry[0] . ")"); } - if ($entry[3] != sprintf("%u", crc32((binary)$data) & 0xffffffff)) { + if ($entry[3] != sprintf("%u", crc32($data) & 0xffffffff)) { die("Invalid internal .phar file (checksum error)"); } diff --git a/ext/phar/tests/bug77432.phpt b/ext/phar/tests/bug77432.phpt index b3b927a5439..3e3a9988c7d 100644 --- a/ext/phar/tests/bug77432.phpt +++ b/ext/phar/tests/bug77432.phpt @@ -38,8 +38,6 @@ include("phar://" . $filename); --- Include 1 --- hello world --- Include 2 --- - -Warning: Constant already defined in %s on line %d hello world --- After unlink --- diff --git a/ext/phar/tests/cache_list/files/phar_test.inc b/ext/phar/tests/cache_list/files/phar_test.inc index bae9415aac4..b30b2f2fce3 100644 --- a/ext/phar/tests/cache_list/files/phar_test.inc +++ b/ext/phar/tests/cache_list/files/phar_test.inc @@ -2,7 +2,7 @@ date_default_timezone_set('UTC'); -$manifest = (binary)''; +$manifest = ''; $glags = 0; foreach($files as $name => $cont) @@ -34,12 +34,12 @@ foreach($files as $name => $cont) if (empty($comp)) $comp = $cont; if (empty($ulen)) $ulen = strlen($cont); if (empty($clen)) $clen = strlen($comp); - if (empty($crc32))$crc32= crc32((binary)$cont); + if (empty($crc32))$crc32= crc32($cont); if (isset($meta)) $meta = serialize($meta); // write manifest entry - $manifest .= pack('V', strlen($name)) . (binary)$name; - $manifest .= pack('VVVVVV', $ulen, $time, $clen, $crc32, $flags|$perm, strlen($meta)) . (binary)$meta; + $manifest .= pack('V', strlen($name)) . $name; + $manifest .= pack('VVVVVV', $ulen, $time, $clen, $crc32, $flags|$perm, strlen($meta)) . $meta; // globals $gflags |= $flags; @@ -50,13 +50,13 @@ if (!isset($alias)) $alias = 'hio'; if (isset($pmeta)) $pmeta = serialize($pmeta); else $pmeta = ''; -$manifest = pack('VnVV', count($files), isset($hasdir) ? 0x1110 : 0x1000, $gflags, strlen($alias)) . (binary)$alias . pack('V', strlen($pmeta)) . (binary)$pmeta . $manifest; -$file = (binary)$file; +$manifest = pack('VnVV', count($files), isset($hasdir) ? 0x1110 : 0x1000, $gflags, strlen($alias)) . $alias . pack('V', strlen($pmeta)) . $pmeta . $manifest; +$file = $file; $file .= pack('V', strlen($manifest)) . $manifest; foreach($files as $cont) { - $file .= (binary)$cont; + $file .= $cont; } file_put_contents($fname, $file); diff --git a/ext/phar/tests/files/phar_oo_test.inc b/ext/phar/tests/files/phar_oo_test.inc index a6f4cee5ee6..b935346bc8e 100644 --- a/ext/phar/tests/files/phar_oo_test.inc +++ b/ext/phar/tests/files/phar_oo_test.inc @@ -5,7 +5,7 @@ ini_set('date.timezone', 'GMT'); $tname = basename(current(get_included_files()), ".php"); $fname = dirname(__FILE__) . "/$tname.phar.php"; $pname = 'phar://' . $fname; -$file = (binary)''; +$file = ''; $files = array(); diff --git a/ext/phar/tests/files/phar_test.inc b/ext/phar/tests/files/phar_test.inc index 277271ef4c6..caf220d0b37 100644 --- a/ext/phar/tests/files/phar_test.inc +++ b/ext/phar/tests/files/phar_test.inc @@ -2,7 +2,7 @@ date_default_timezone_set('UTC'); -$manifest = (binary)''; +$manifest = ''; $gflags = 0; foreach($files as $name => $cont) @@ -34,12 +34,12 @@ foreach($files as $name => $cont) if (empty($comp)) $comp = $cont; if (empty($ulen)) $ulen = strlen($cont); if (empty($clen)) $clen = strlen($comp); - if (empty($crc32))$crc32= crc32((binary)$cont); + if (empty($crc32))$crc32= crc32($cont); $meta = isset($meta) ? serialize($meta) : ""; // write manifest entry - $manifest .= pack('V', strlen($name)) . (binary)$name; - $manifest .= pack('VVVVVV', $ulen, $time, $clen, $crc32, $flags|$perm, strlen($meta)) . (binary)$meta; + $manifest .= pack('V', strlen($name)) . $name; + $manifest .= pack('VVVVVV', $ulen, $time, $clen, $crc32, $flags|$perm, strlen($meta)) . $meta; // globals $gflags |= $flags; @@ -50,13 +50,13 @@ if (!isset($alias)) $alias = 'hio'; if (isset($pmeta)) $pmeta = serialize($pmeta); else $pmeta = ''; -$manifest = pack('VnVV', count($files), isset($hasdir) ? 0x1110 : 0x1000, $gflags, strlen($alias)) . (binary)$alias . pack('V', strlen($pmeta)) . (binary)$pmeta . $manifest; -$file = (binary)$file; +$manifest = pack('VnVV', count($files), isset($hasdir) ? 0x1110 : 0x1000, $gflags, strlen($alias)) . $alias . pack('V', strlen($pmeta)) . $pmeta . $manifest; +$file = $file; $file .= pack('V', strlen($manifest)) . $manifest; foreach($files as $cont) { - $file .= (binary)$cont; + $file .= $cont; } file_put_contents($fname, $file); diff --git a/ext/phar/tests/tar/files/make.dangerous.tar.php.inc b/ext/phar/tests/tar/files/make.dangerous.tar.php.inc index 641dda56f59..ff9c20ccf9b 100644 --- a/ext/phar/tests/tar/files/make.dangerous.tar.php.inc +++ b/ext/phar/tests/tar/files/make.dangerous.tar.php.inc @@ -108,16 +108,16 @@ class danger_tarmaker $checksum = pack('a8', sprintf('%6s ', decoct($checksum))); - fwrite($this->tmp, (binary)$block . $checksum . $blockend, 512); + fwrite($this->tmp, $block . $checksum . $blockend, 512); if (is_resource($fileOrStream)) { stream_copy_to_stream($fileOrStream, $this->tmp); if ($stat['size'] % 512) { - fwrite($this->tmp, (binary)str_repeat("\0", 512 - $stat['size'] % 512)); + fwrite($this->tmp, str_repeat("\0", 512 - $stat['size'] % 512)); } } else { - fwrite($this->tmp, (binary)$fileOrStream); + fwrite($this->tmp, $fileOrStream); if (strlen($fileOrStream) % 512) { - fwrite($this->tmp, (binary)str_repeat("\0", 512 - strlen($fileOrStream) % 512)); + fwrite($this->tmp, str_repeat("\0", 512 - strlen($fileOrStream) % 512)); } } } diff --git a/ext/phar/tests/tar/files/make_invalid_tar.php.inc b/ext/phar/tests/tar/files/make_invalid_tar.php.inc index 2ccdf00201c..cf9034bc307 100644 --- a/ext/phar/tests/tar/files/make_invalid_tar.php.inc +++ b/ext/phar/tests/tar/files/make_invalid_tar.php.inc @@ -3,7 +3,7 @@ include dirname(__FILE__) . '/tarmaker.php.inc'; class corrupter extends tarmaker { function close() { - fwrite($this->tmp, (binary)'oopsie'); + fwrite($this->tmp, 'oopsie'); fclose($this->tmp); } } diff --git a/ext/phar/tests/tar/files/tarmaker.php.inc b/ext/phar/tests/tar/files/tarmaker.php.inc index 5860bf84d31..ce0bd249b51 100644 --- a/ext/phar/tests/tar/files/tarmaker.php.inc +++ b/ext/phar/tests/tar/files/tarmaker.php.inc @@ -107,16 +107,16 @@ class tarmaker $checksum = pack('a8', sprintf('%6s ', decoct($checksum))); - fwrite($this->tmp, (binary)$block . $checksum . $blockend, 512); + fwrite($this->tmp, $block . $checksum . $blockend, 512); if (is_resource($fileOrStream)) { stream_copy_to_stream($fileOrStream, $this->tmp); if ($stat['size'] % 512) { - fwrite($this->tmp, (binary)str_repeat("\0", 512 - $stat['size'] % 512)); + fwrite($this->tmp, str_repeat("\0", 512 - $stat['size'] % 512)); } } else { - fwrite($this->tmp, (binary)$fileOrStream); + fwrite($this->tmp, $fileOrStream); if (strlen($fileOrStream) % 512) { - fwrite($this->tmp, (binary)str_repeat("\0", 512 - strlen($fileOrStream) % 512)); + fwrite($this->tmp, str_repeat("\0", 512 - strlen($fileOrStream) % 512)); } } } diff --git a/ext/posix/posix.c b/ext/posix/posix.c index 512776d3ced..ff878b3acfc 100644 --- a/ext/posix/posix.c +++ b/ext/posix/posix.c @@ -45,6 +45,14 @@ # include #endif +#if (defined(__sun) && !defined(_LP64)) || defined(_AIX) +#define POSIX_PID_MIN LONG_MIN +#define POSIX_PID_MAX LONG_MAX +#else +#define POSIX_PID_MIN INT_MIN +#define POSIX_PID_MAX INT_MAX +#endif + #include "posix_arginfo.h" ZEND_DECLARE_MODULE_GLOBALS(posix) @@ -118,6 +126,12 @@ ZEND_GET_MODULE(posix) } \ RETURN_TRUE; +#define PHP_POSIX_CHECK_PID(pid, arg, lower, upper) \ + if (pid < lower || pid > upper) { \ + zend_argument_value_error(arg, "must be between " ZEND_LONG_FMT " and " ZEND_LONG_FMT, lower, upper); \ + RETURN_THROWS(); \ + } + /* {{{ Send a signal to a process (POSIX.1, 3.3.2) */ PHP_FUNCTION(posix_kill) @@ -129,6 +143,8 @@ PHP_FUNCTION(posix_kill) Z_PARAM_LONG(sig) ZEND_PARSE_PARAMETERS_END(); + PHP_POSIX_CHECK_PID(pid, 1, POSIX_PID_MIN, POSIX_PID_MAX) + if (kill(pid, sig) < 0) { POSIX_G(last_error) = errno; RETURN_FALSE; @@ -291,6 +307,9 @@ PHP_FUNCTION(posix_setpgid) Z_PARAM_LONG(pgid) ZEND_PARSE_PARAMETERS_END(); + PHP_POSIX_CHECK_PID(pid, 1, 0, POSIX_PID_MAX) + PHP_POSIX_CHECK_PID(pgid, 2, 0, POSIX_PID_MAX) + if (setpgid(pid, pgid) < 0) { POSIX_G(last_error) = errno; RETURN_FALSE; @@ -329,6 +348,8 @@ PHP_FUNCTION(posix_getsid) Z_PARAM_LONG(val) ZEND_PARSE_PARAMETERS_END(); + PHP_POSIX_CHECK_PID(val, 1, 0, POSIX_PID_MAX) + if ((val = getsid(val)) < 0) { POSIX_G(last_error) = errno; RETURN_FALSE; @@ -1183,6 +1204,21 @@ PHP_FUNCTION(posix_setrlimit) Z_PARAM_LONG(max) ZEND_PARSE_PARAMETERS_END(); + if (cur < -1) { + zend_argument_value_error(2, "must be greater or equal to -1"); + RETURN_THROWS(); + } + + if (max < -1) { + zend_argument_value_error(3, "must be greater or equal to -1"); + RETURN_THROWS(); + } + + if (max > -1 && cur > max) { + zend_argument_value_error(2, "must be lower or equal to " ZEND_LONG_FMT, max); + RETURN_THROWS(); + } + rl.rlim_cur = cur; rl.rlim_max = max; diff --git a/ext/posix/tests/posix_getsid_error.phpt b/ext/posix/tests/posix_getsid_error.phpt index c62eca58a84..68f16855499 100644 --- a/ext/posix/tests/posix_getsid_error.phpt +++ b/ext/posix/tests/posix_getsid_error.phpt @@ -9,7 +9,11 @@ PHP Testfest Berlin 2009-05-10 posix --FILE-- getMessage(), PHP_EOL; +} ?> ---EXPECT-- -bool(false) +--EXPECTF-- +posix_getsid(): Argument #1 ($process_id) must be between 0 and %d diff --git a/ext/posix/tests/posix_kill_pidoverflow.phpt b/ext/posix/tests/posix_kill_pidoverflow.phpt new file mode 100644 index 00000000000..0e8b8c7b7df --- /dev/null +++ b/ext/posix/tests/posix_kill_pidoverflow.phpt @@ -0,0 +1,25 @@ +--TEST-- +posix_kill() with large pid +--EXTENSIONS-- +posix +pcntl +--SKIPIF-- + +--FILE-- +getMessage(), PHP_EOL; +} + +try { + posix_kill(PHP_INT_MIN, SIGTERM); +} catch (\ValueError $e) { + echo $e->getMessage(), PHP_EOL; +} +?> +--EXPECTF-- +posix_kill(): Argument #1 ($process_id) must be between %i and %d +posix_kill(): Argument #1 ($process_id) must be between %i and %d diff --git a/ext/posix/tests/posix_setpgid_error.phpt b/ext/posix/tests/posix_setpgid_error.phpt new file mode 100644 index 00000000000..0d00dd87c60 --- /dev/null +++ b/ext/posix/tests/posix_setpgid_error.phpt @@ -0,0 +1,34 @@ +--TEST-- +posix_setpgid() with wrong pid values +--EXTENSIONS-- +posix +--SKIPIF-- + +--FILE-- +getMessage(), PHP_EOL; +} +try { + posix_setpgid(-2, 1); +} catch (\ValueError $e) { + echo $e->getMessage(), PHP_EOL; +} +try { + posix_setpgid(1, PHP_INT_MAX); +} catch (\ValueError $e) { + echo $e->getMessage(), PHP_EOL; +} +try { + posix_setpgid(1, -2); +} catch (\ValueError $e) { + echo $e->getMessage(), PHP_EOL; +} +?> +--EXPECTF-- +posix_setpgid(): Argument #1 ($process_id) must be between 0 and %d +posix_setpgid(): Argument #1 ($process_id) must be between 0 and %d +posix_setpgid(): Argument #2 ($process_group_id) must be between 0 and %d +posix_setpgid(): Argument #2 ($process_group_id) must be between 0 and %d diff --git a/ext/posix/tests/posix_setrlimit.phpt b/ext/posix/tests/posix_setrlimit.phpt index cc8fadafc04..51638793f9d 100644 --- a/ext/posix/tests/posix_setrlimit.phpt +++ b/ext/posix/tests/posix_setrlimit.phpt @@ -12,9 +12,25 @@ if (str_contains(PHP_OS, 'FreeBSD')) die('skip different behavior on FreeBSD'); getMessage(), PHP_EOL; +} +try { + posix_setrlimit(POSIX_RLIMIT_NOFILE, -2, -1); +} catch (\ValueError $e) { + echo $e->getMessage(), PHP_EOL; +} +try { + posix_setrlimit(POSIX_RLIMIT_NOFILE, -1, -2); +} catch (\ValueError $e) { + echo $e->getMessage(), PHP_EOL; +} ?> --EXPECT-- bool(true) -bool(false) +posix_setrlimit(): Argument #2 ($soft_limit) must be lower or equal to 128 +posix_setrlimit(): Argument #2 ($soft_limit) must be greater or equal to -1 +posix_setrlimit(): Argument #3 ($hard_limit) must be greater or equal to -1 diff --git a/ext/random/random_arginfo.h b/ext/random/random_arginfo.h index 0cda5467deb..ec22af1bd2b 100644 --- a/ext/random/random_arginfo.h +++ b/ext/random/random_arginfo.h @@ -232,19 +232,15 @@ static void register_random_symbols(int module_number) zend_attribute *attribute_Deprecated_func_lcg_value_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "lcg_value", sizeof("lcg_value") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_func_lcg_value_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_4)); attribute_Deprecated_func_lcg_value_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_lcg_value_0_arg1; zend_string *attribute_Deprecated_func_lcg_value_0_arg1_str = zend_string_init("use \\Random\\Randomizer::getFloat() instead", strlen("use \\Random\\Randomizer::getFloat() instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_lcg_value_0_arg1, attribute_Deprecated_func_lcg_value_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_lcg_value_0->args[1].value, &attribute_Deprecated_func_lcg_value_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_lcg_value_0->args[1].value, attribute_Deprecated_func_lcg_value_0_arg1_str); attribute_Deprecated_func_lcg_value_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_const_MT_RAND_PHP_0 = zend_add_global_constant_attribute(const_MT_RAND_PHP, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_const_MT_RAND_PHP_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_3)); attribute_Deprecated_const_MT_RAND_PHP_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_const_MT_RAND_PHP_0_arg1; zend_string *attribute_Deprecated_const_MT_RAND_PHP_0_arg1_str = zend_string_init("as it uses a biased non-standard variant of Mt19937", strlen("as it uses a biased non-standard variant of Mt19937"), 1); - ZVAL_STR(&attribute_Deprecated_const_MT_RAND_PHP_0_arg1, attribute_Deprecated_const_MT_RAND_PHP_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_const_MT_RAND_PHP_0->args[1].value, &attribute_Deprecated_const_MT_RAND_PHP_0_arg1); + ZVAL_STR(&attribute_Deprecated_const_MT_RAND_PHP_0->args[1].value, attribute_Deprecated_const_MT_RAND_PHP_0_arg1_str); attribute_Deprecated_const_MT_RAND_PHP_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); } diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index 74dcd772dc7..b5ca21d500a 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -716,7 +716,7 @@ static zval *get_default_from_recv(zend_op_array *op_array, uint32_t offset) { return RT_CONSTANT(recv, recv->op2); } -static int format_default_value(smart_str *str, zval *value) { +static void format_default_value(smart_str *str, zval *value) { if (smart_str_append_zval(str, value, SIZE_MAX) == SUCCESS) { /* Nothing to do. */ } else if (Z_TYPE_P(value) == IS_ARRAY) { @@ -761,7 +761,6 @@ static int format_default_value(smart_str *str, zval *value) { smart_str_append(str, ast_str); zend_string_release(ast_str); } - return SUCCESS; } static inline bool has_internal_arg_info(const zend_function *fptr) { @@ -808,9 +807,7 @@ static void _parameter_string(smart_str *str, zend_function *fptr, struct _zend_ zval *default_value = get_default_from_recv((zend_op_array*)fptr, offset); if (default_value) { smart_str_appends(str, " = "); - if (format_default_value(str, default_value) == FAILURE) { - return; - } + format_default_value(str, default_value); } } } @@ -1040,6 +1037,9 @@ static void _property_string(smart_str *str, zend_property_info *prop, const cha if (prop->flags & ZEND_ACC_READONLY) { smart_str_appends(str, "readonly "); } + if (prop->flags & ZEND_ACC_VIRTUAL) { + smart_str_appends(str, "virtual "); + } if (ZEND_TYPE_IS_SET(prop->type)) { zend_string *type_str = zend_type_to_string(prop->type); smart_str_append(str, type_str); @@ -1055,9 +1055,27 @@ static void _property_string(smart_str *str, zend_property_info *prop, const cha zval *default_value = property_get_default(prop); if (default_value && !Z_ISUNDEF_P(default_value)) { smart_str_appends(str, " = "); - if (format_default_value(str, default_value) == FAILURE) { - return; + format_default_value(str, default_value); + } + if (prop->hooks != NULL) { + smart_str_appends(str, " {"); + const zend_function *get_hooked = prop->hooks[ZEND_PROPERTY_HOOK_GET]; + if (get_hooked != NULL) { + if (get_hooked->common.fn_flags & ZEND_ACC_FINAL) { + smart_str_appends(str, " final get;"); + } else { + smart_str_appends(str, " get;"); + } } + const zend_function *set_hooked = prop->hooks[ZEND_PROPERTY_HOOK_SET]; + if (set_hooked != NULL) { + if (set_hooked->common.fn_flags & ZEND_ACC_FINAL) { + smart_str_appends(str, " final set;"); + } else { + smart_str_appends(str, " set;"); + } + } + smart_str_appends(str, " }"); } } @@ -4837,6 +4855,11 @@ ZEND_METHOD(ReflectionClass, getConstant) } } ZEND_HASH_FOREACH_END(); if ((c = zend_hash_find_ptr(constants_table, name)) == NULL) { + zend_error( + E_DEPRECATED, + "ReflectionClass::getConstant() for a non-existent constant is deprecated, " + "use ReflectionClass::hasConstant() to check if the constant exists" + ); RETURN_FALSE; } ZVAL_COPY_OR_DUP(return_value, &c->value); @@ -5753,6 +5776,21 @@ ZEND_METHOD(ReflectionProperty, getName) } /* }}} */ +ZEND_METHOD(ReflectionProperty, getMangledName) +{ + reflection_object *intern; + property_reference *ref; + + ZEND_PARSE_PARAMETERS_NONE(); + + GET_REFLECTION_OBJECT_PTR(ref); + if (ref->prop == NULL) { + RETURN_STR_COPY(ref->unmangled_name); + } + + RETURN_STR_COPY(ref->prop->name); +} + static void _property_check_flag(INTERNAL_FUNCTION_PARAMETERS, int mask) /* {{{ */ { reflection_object *intern; @@ -6403,7 +6441,7 @@ ZEND_METHOD(ReflectionProperty, getSettableType) /* Get-only virtual property can never be written to. */ if (prop->hooks && (prop->flags & ZEND_ACC_VIRTUAL) && !prop->hooks[ZEND_PROPERTY_HOOK_SET]) { zend_type never_type = ZEND_TYPE_INIT_CODE(IS_NEVER, 0, 0); - reflection_type_factory(never_type, return_value, 0); + reflection_type_factory(never_type, return_value, 1); return; } @@ -6413,7 +6451,7 @@ ZEND_METHOD(ReflectionProperty, getSettableType) if (!ZEND_TYPE_IS_SET(arg_info->type)) { RETURN_NULL(); } - reflection_type_factory(arg_info->type, return_value, 0); + reflection_type_factory(arg_info->type, return_value, 1); return; } @@ -6421,7 +6459,7 @@ ZEND_METHOD(ReflectionProperty, getSettableType) if (!ZEND_TYPE_IS_SET(ref->prop->type)) { RETURN_NULL(); } - reflection_type_factory(ref->prop->type, return_value, 0); + reflection_type_factory(ref->prop->type, return_value, 1); } /* {{{ Returns whether property has a type */ @@ -6476,11 +6514,22 @@ ZEND_METHOD(ReflectionProperty, getDefaultValue) prop_info = ref->prop; if (prop_info == NULL) { - return; // throw exception? + // Dynamic property + zend_error( + E_DEPRECATED, + "ReflectionProperty::getDefaultValue() for a property without a default value is deprecated, " + "use ReflectionProperty::hasDefaultValue() to check if the default value exists" + ); + return; } prop = property_get_default(prop_info); if (!prop || Z_ISUNDEF_P(prop)) { + zend_error( + E_DEPRECATED, + "ReflectionProperty::getDefaultValue() for a property without a default value is deprecated, " + "use ReflectionProperty::hasDefaultValue() to check if the default value exists" + ); return; } @@ -7166,10 +7215,7 @@ ZEND_METHOD(ReflectionAttribute, __toString) smart_str_appends(&str, " = "); } - if (format_default_value(&str, &attr->data->args[i].value) == FAILURE) { - smart_str_free(&str); - RETURN_THROWS(); - } + format_default_value(&str, &attr->data->args[i].value); smart_str_appends(&str, " ]\n"); } diff --git a/ext/reflection/php_reflection.stub.php b/ext/reflection/php_reflection.stub.php index 63518b446ad..7af884953be 100644 --- a/ext/reflection/php_reflection.stub.php +++ b/ext/reflection/php_reflection.stub.php @@ -226,6 +226,7 @@ class ReflectionMethod extends ReflectionFunctionAbstract public function hasPrototype(): bool {} /** @tentative-return-type */ + #[\Deprecated(since: '8.5', message: "as it has no effect")] public function setAccessible(bool $accessible): void {} } @@ -482,6 +483,8 @@ class ReflectionProperty implements Reflector /** @tentative-return-type */ public function getName(): string {} + public function getMangledName(): string {} + /** @tentative-return-type */ public function getValue(?object $object = null): mixed {} @@ -540,6 +543,7 @@ class ReflectionProperty implements Reflector public function getDocComment(): string|false {} /** @tentative-return-type */ + #[\Deprecated(since: '8.5', message: "as it has no effect")] public function setAccessible(bool $accessible): void {} /** @tentative-return-type */ diff --git a/ext/reflection/php_reflection_arginfo.h b/ext/reflection/php_reflection_arginfo.h index b1d310c2a0c..907ada13efa 100644 --- a/ext/reflection/php_reflection_arginfo.h +++ b/ext/reflection/php_reflection_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 7a8d126a96f0115783bd20a9adfc6bdc5ee88fda */ + * Stub hash: 0f6ecac0c6c4fb4af140a1be95f6a50c7532dae9 */ ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_Reflection_getModifierNames, 0, 1, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO(0, modifiers, IS_LONG, 0) @@ -381,6 +381,8 @@ ZEND_END_ARG_INFO() #define arginfo_class_ReflectionProperty_getName arginfo_class_ReflectionFunctionAbstract_getName +#define arginfo_class_ReflectionProperty_getMangledName arginfo_class_ReflectionFunction___toString + ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_ReflectionProperty_getValue, 0, 0, IS_MIXED, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, object, IS_OBJECT, 1, "null") ZEND_END_ARG_INFO() @@ -853,6 +855,7 @@ ZEND_METHOD(ReflectionObject, __construct); ZEND_METHOD(ReflectionProperty, __construct); ZEND_METHOD(ReflectionProperty, __toString); ZEND_METHOD(ReflectionProperty, getName); +ZEND_METHOD(ReflectionProperty, getMangledName); ZEND_METHOD(ReflectionProperty, getValue); ZEND_METHOD(ReflectionProperty, setValue); ZEND_METHOD(ReflectionProperty, getRawValue); @@ -1073,7 +1076,7 @@ static const zend_function_entry class_ReflectionMethod_methods[] = { ZEND_ME(ReflectionMethod, getDeclaringClass, arginfo_class_ReflectionMethod_getDeclaringClass, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionMethod, getPrototype, arginfo_class_ReflectionMethod_getPrototype, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionMethod, hasPrototype, arginfo_class_ReflectionMethod_hasPrototype, ZEND_ACC_PUBLIC) - ZEND_ME(ReflectionMethod, setAccessible, arginfo_class_ReflectionMethod_setAccessible, ZEND_ACC_PUBLIC) + ZEND_ME(ReflectionMethod, setAccessible, arginfo_class_ReflectionMethod_setAccessible, ZEND_ACC_PUBLIC|ZEND_ACC_DEPRECATED) ZEND_FE_END }; @@ -1155,6 +1158,7 @@ static const zend_function_entry class_ReflectionProperty_methods[] = { ZEND_ME(ReflectionProperty, __construct, arginfo_class_ReflectionProperty___construct, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionProperty, __toString, arginfo_class_ReflectionProperty___toString, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionProperty, getName, arginfo_class_ReflectionProperty_getName, ZEND_ACC_PUBLIC) + ZEND_ME(ReflectionProperty, getMangledName, arginfo_class_ReflectionProperty_getMangledName, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionProperty, getValue, arginfo_class_ReflectionProperty_getValue, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionProperty, setValue, arginfo_class_ReflectionProperty_setValue, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionProperty, getRawValue, arginfo_class_ReflectionProperty_getRawValue, ZEND_ACC_PUBLIC) @@ -1178,7 +1182,7 @@ static const zend_function_entry class_ReflectionProperty_methods[] = { ZEND_ME(ReflectionProperty, getModifiers, arginfo_class_ReflectionProperty_getModifiers, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionProperty, getDeclaringClass, arginfo_class_ReflectionProperty_getDeclaringClass, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionProperty, getDocComment, arginfo_class_ReflectionProperty_getDocComment, ZEND_ACC_PUBLIC) - ZEND_ME(ReflectionProperty, setAccessible, arginfo_class_ReflectionProperty_setAccessible, ZEND_ACC_PUBLIC) + ZEND_ME(ReflectionProperty, setAccessible, arginfo_class_ReflectionProperty_setAccessible, ZEND_ACC_PUBLIC|ZEND_ACC_DEPRECATED) ZEND_ME(ReflectionProperty, getType, arginfo_class_ReflectionProperty_getType, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionProperty, getSettableType, arginfo_class_ReflectionProperty_getSettableType, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionProperty, hasType, arginfo_class_ReflectionProperty_hasType, ZEND_ACC_PUBLIC) @@ -1425,10 +1429,8 @@ static zend_class_entry *register_class_ReflectionFunction(zend_class_entry *cla zend_attribute *attribute_Deprecated_func_isdisabled_0 = zend_add_function_attribute(zend_hash_str_find_ptr(&class_entry->function_table, "isdisabled", sizeof("isdisabled") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_func_isdisabled_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_func_isdisabled_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_isdisabled_0_arg1; zend_string *attribute_Deprecated_func_isdisabled_0_arg1_str = zend_string_init("as ReflectionFunction can no longer be constructed for disabled functions", strlen("as ReflectionFunction can no longer be constructed for disabled functions"), 1); - ZVAL_STR(&attribute_Deprecated_func_isdisabled_0_arg1, attribute_Deprecated_func_isdisabled_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_isdisabled_0->args[1].value, &attribute_Deprecated_func_isdisabled_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_isdisabled_0->args[1].value, attribute_Deprecated_func_isdisabled_0_arg1_str); attribute_Deprecated_func_isdisabled_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); return class_entry; @@ -1491,6 +1493,14 @@ static zend_class_entry *register_class_ReflectionMethod(zend_class_entry *class ZVAL_UNDEF(&property_class_default_value); zend_declare_typed_property(class_entry, ZSTR_KNOWN(ZEND_STR_CLASS), &property_class_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + + zend_attribute *attribute_Deprecated_func_setaccessible_0 = zend_add_function_attribute(zend_hash_str_find_ptr(&class_entry->function_table, "setaccessible", sizeof("setaccessible") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + ZVAL_STR(&attribute_Deprecated_func_setaccessible_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_5)); + attribute_Deprecated_func_setaccessible_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zend_string *attribute_Deprecated_func_setaccessible_0_arg1_str = zend_string_init("as it has no effect", strlen("as it has no effect"), 1); + ZVAL_STR(&attribute_Deprecated_func_setaccessible_0->args[1].value, attribute_Deprecated_func_setaccessible_0_arg1_str); + attribute_Deprecated_func_setaccessible_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + return class_entry; } @@ -1648,6 +1658,14 @@ static zend_class_entry *register_class_ReflectionProperty(zend_class_entry *cla ZVAL_UNDEF(&property_class_default_value); zend_declare_typed_property(class_entry, ZSTR_KNOWN(ZEND_STR_CLASS), &property_class_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + + zend_attribute *attribute_Deprecated_func_setaccessible_0 = zend_add_function_attribute(zend_hash_str_find_ptr(&class_entry->function_table, "setaccessible", sizeof("setaccessible") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + ZVAL_STR(&attribute_Deprecated_func_setaccessible_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_5)); + attribute_Deprecated_func_setaccessible_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zend_string *attribute_Deprecated_func_setaccessible_0_arg1_str = zend_string_init("as it has no effect", strlen("as it has no effect"), 1); + ZVAL_STR(&attribute_Deprecated_func_setaccessible_0->args[1].value, attribute_Deprecated_func_setaccessible_0_arg1_str); + attribute_Deprecated_func_setaccessible_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + return class_entry; } @@ -1710,28 +1728,20 @@ static zend_class_entry *register_class_ReflectionParameter(zend_class_entry *cl zend_attribute *attribute_Deprecated_func_getclass_0 = zend_add_function_attribute(zend_hash_str_find_ptr(&class_entry->function_table, "getclass", sizeof("getclass") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_func_getclass_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_func_getclass_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_getclass_0_arg1; zend_string *attribute_Deprecated_func_getclass_0_arg1_str = zend_string_init("use ReflectionParameter::getType() instead", strlen("use ReflectionParameter::getType() instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_getclass_0_arg1, attribute_Deprecated_func_getclass_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_getclass_0->args[1].value, &attribute_Deprecated_func_getclass_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_getclass_0->args[1].value, attribute_Deprecated_func_getclass_0_arg1_str); attribute_Deprecated_func_getclass_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_func_isarray_0 = zend_add_function_attribute(zend_hash_str_find_ptr(&class_entry->function_table, "isarray", sizeof("isarray") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_func_isarray_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_func_isarray_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_isarray_0_arg1; - zend_string *attribute_Deprecated_func_isarray_0_arg1_str = zend_string_init("use ReflectionParameter::getType() instead", strlen("use ReflectionParameter::getType() instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_isarray_0_arg1, attribute_Deprecated_func_isarray_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_isarray_0->args[1].value, &attribute_Deprecated_func_isarray_0_arg1); + ZVAL_STR_COPY(&attribute_Deprecated_func_isarray_0->args[1].value, attribute_Deprecated_func_getclass_0_arg1_str); attribute_Deprecated_func_isarray_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_func_iscallable_0 = zend_add_function_attribute(zend_hash_str_find_ptr(&class_entry->function_table, "iscallable", sizeof("iscallable") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_func_iscallable_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_func_iscallable_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_iscallable_0_arg1; - zend_string *attribute_Deprecated_func_iscallable_0_arg1_str = zend_string_init("use ReflectionParameter::getType() instead", strlen("use ReflectionParameter::getType() instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_iscallable_0_arg1, attribute_Deprecated_func_iscallable_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_iscallable_0->args[1].value, &attribute_Deprecated_func_iscallable_0_arg1); + ZVAL_STR_COPY(&attribute_Deprecated_func_iscallable_0->args[1].value, attribute_Deprecated_func_getclass_0_arg1_str); attribute_Deprecated_func_iscallable_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); return class_entry; diff --git a/ext/reflection/tests/022.phpt b/ext/reflection/tests/022.phpt index 4a6738f97cd..7a78397a76f 100644 --- a/ext/reflection/tests/022.phpt +++ b/ext/reflection/tests/022.phpt @@ -9,6 +9,8 @@ $class = new ReflectionClass("Foo"); var_dump($class->getConstant("c1")); var_dump($class->getConstant("c2")); ?> ---EXPECT-- +--EXPECTF-- int(1) + +Deprecated: ReflectionClass::getConstant() for a non-existent constant is deprecated, use ReflectionClass::hasConstant() to check if the constant exists in %s on line %d bool(false) diff --git a/ext/reflection/tests/ReflectionClass_getConstant_basic.phpt b/ext/reflection/tests/ReflectionClass_getConstant_basic.phpt index 67d1eee7e83..a8864c5970a 100644 --- a/ext/reflection/tests/ReflectionClass_getConstant_basic.phpt +++ b/ext/reflection/tests/ReflectionClass_getConstant_basic.phpt @@ -23,19 +23,31 @@ foreach($classes as $class) { var_dump($rc->getConstant('doesnotexist')); } ?> ---EXPECT-- +--EXPECTF-- Reflecting on class C: string(12) "hello from C" + +Deprecated: ReflectionClass::getConstant() for a non-existent constant is deprecated, use ReflectionClass::hasConstant() to check if the constant exists in %s on line %d bool(false) Reflecting on class D: string(12) "hello from C" + +Deprecated: ReflectionClass::getConstant() for a non-existent constant is deprecated, use ReflectionClass::hasConstant() to check if the constant exists in %s on line %d bool(false) Reflecting on class E: string(12) "hello from C" + +Deprecated: ReflectionClass::getConstant() for a non-existent constant is deprecated, use ReflectionClass::hasConstant() to check if the constant exists in %s on line %d bool(false) Reflecting on class F: string(12) "hello from F" + +Deprecated: ReflectionClass::getConstant() for a non-existent constant is deprecated, use ReflectionClass::hasConstant() to check if the constant exists in %s on line %d bool(false) Reflecting on class X: + +Deprecated: ReflectionClass::getConstant() for a non-existent constant is deprecated, use ReflectionClass::hasConstant() to check if the constant exists in %s on line %d bool(false) + +Deprecated: ReflectionClass::getConstant() for a non-existent constant is deprecated, use ReflectionClass::hasConstant() to check if the constant exists in %s on line %d bool(false) diff --git a/ext/reflection/tests/ReflectionClass_getConstant_error.phpt b/ext/reflection/tests/ReflectionClass_getConstant_error.phpt index d143006af99..caadf2e3713 100644 --- a/ext/reflection/tests/ReflectionClass_getConstant_error.phpt +++ b/ext/reflection/tests/ReflectionClass_getConstant_error.phpt @@ -12,8 +12,14 @@ var_dump($rc->getConstant(1)); var_dump($rc->getConstant(1.5)); var_dump($rc->getConstant(true)); ?> ---EXPECT-- +--EXPECTF-- Check invalid params: + +Deprecated: ReflectionClass::getConstant() for a non-existent constant is deprecated, use ReflectionClass::hasConstant() to check if the constant exists in %s on line %d bool(false) + +Deprecated: ReflectionClass::getConstant() for a non-existent constant is deprecated, use ReflectionClass::hasConstant() to check if the constant exists in %s on line %d bool(false) + +Deprecated: ReflectionClass::getConstant() for a non-existent constant is deprecated, use ReflectionClass::hasConstant() to check if the constant exists in %s on line %d bool(false) diff --git a/ext/reflection/tests/ReflectionClass_toString_008.phpt b/ext/reflection/tests/ReflectionClass_toString_008.phpt new file mode 100644 index 00000000000..15131cfd880 --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_toString_008.phpt @@ -0,0 +1,165 @@ +--TEST-- +Using ReflectionClass::__toString() with hooked properties (GH-17927) +--FILE-- + "always this string"; + } + public mixed $setOnly { + set => strtolower($value); + } + public mixed $both { + get => $this->prop3; + set => strtolower($value); + } +} +class WithFinalHooks { + public mixed $getOnly { + final get => "always this string"; + } + public mixed $setOnly { + final set => strtolower($value); + } + public mixed $both { + final get => $this->prop3; + final set => strtolower($value); + } +} +class WithMixedHooks { + public mixed $getIsFinal { + final get => "always this string"; + set => strtolower($value); + } + public mixed $setIsFinal { + get => $this->setIsFinal; + final set => strtolower($value); + } +} +$classes = [ + IHookedDemo::class, + HookedDemo::class, + WithHooks::class, + WithFinalHooks::class, + WithMixedHooks::class, +]; +foreach ( $classes as $clazz ) { + echo new ReflectionClass( $clazz ); +} +?> +--EXPECTF-- +Interface [ interface IHookedDemo ] { + @@ %s %d-%d + + - Constants [0] { + } + + - Static properties [0] { + } + + - Static methods [0] { + } + + - Properties [3] { + Property [ abstract public virtual mixed $getOnly { get; } ] + Property [ abstract public virtual mixed $setOnly { set; } ] + Property [ abstract public virtual mixed $both { get; set; } ] + } + + - Methods [0] { + } +} +Class [ abstract class HookedDemo ] { + @@ %s %d-%d + + - Constants [0] { + } + + - Static properties [0] { + } + + - Static methods [0] { + } + + - Properties [3] { + Property [ abstract public virtual mixed $getOnly { get; } ] + Property [ abstract public virtual mixed $setOnly { set; } ] + Property [ abstract public virtual mixed $both { get; set; } ] + } + + - Methods [0] { + } +} +Class [ class WithHooks ] { + @@ %s %d-%d + + - Constants [0] { + } + + - Static properties [0] { + } + + - Static methods [0] { + } + + - Properties [3] { + Property [ public virtual mixed $getOnly { get; } ] + Property [ public mixed $setOnly { set; } ] + Property [ public mixed $both { get; set; } ] + } + + - Methods [0] { + } +} +Class [ class WithFinalHooks ] { + @@ %s %d-%d + + - Constants [0] { + } + + - Static properties [0] { + } + + - Static methods [0] { + } + + - Properties [3] { + Property [ public virtual mixed $getOnly { final get; } ] + Property [ public mixed $setOnly { final set; } ] + Property [ public mixed $both { final get; final set; } ] + } + + - Methods [0] { + } +} +Class [ class WithMixedHooks ] { + @@ %s %d-%d + + - Constants [0] { + } + + - Static properties [0] { + } + + - Static methods [0] { + } + + - Properties [2] { + Property [ public mixed $getIsFinal { final get; set; } ] + Property [ public mixed $setIsFinal { get; final set; } ] + } + + - Methods [0] { + } +} diff --git a/ext/reflection/tests/ReflectionMethod_setAccessible.phpt b/ext/reflection/tests/ReflectionMethod_setAccessible.phpt index 92312528a04..ba4864d28ed 100644 --- a/ext/reflection/tests/ReflectionMethod_setAccessible.phpt +++ b/ext/reflection/tests/ReflectionMethod_setAccessible.phpt @@ -37,7 +37,7 @@ $protected->invokeArgs(new A, array(NULL)); $protectedStatic->invoke(NULL, NULL); $protectedStatic->invokeArgs(NULL, array(NULL)); ?> ---EXPECT-- +--EXPECTF-- A::aPrivate A::aPrivate A::aPrivateStatic @@ -46,6 +46,14 @@ A::aProtected A::aProtected A::aProtectedStatic A::aProtectedStatic + +Deprecated: Method ReflectionMethod::setAccessible() is deprecated since 8.5, as it has no effect in %s on line %d + +Deprecated: Method ReflectionMethod::setAccessible() is deprecated since 8.5, as it has no effect in %s on line %d + +Deprecated: Method ReflectionMethod::setAccessible() is deprecated since 8.5, as it has no effect in %s on line %d + +Deprecated: Method ReflectionMethod::setAccessible() is deprecated since 8.5, as it has no effect in %s on line %d A::aPrivate A::aPrivate A::aPrivateStatic diff --git a/ext/reflection/tests/ReflectionObject_getConstant_basic.phpt b/ext/reflection/tests/ReflectionObject_getConstant_basic.phpt index c132f1121a1..fec75b40eb2 100644 --- a/ext/reflection/tests/ReflectionObject_getConstant_basic.phpt +++ b/ext/reflection/tests/ReflectionObject_getConstant_basic.phpt @@ -23,19 +23,31 @@ foreach($classes as $class) { var_dump($rc->getConstant('doesNotexist')); } ?> ---EXPECT-- +--EXPECTF-- Reflecting on instance of class C: string(12) "hello from C" + +Deprecated: ReflectionClass::getConstant() for a non-existent constant is deprecated, use ReflectionClass::hasConstant() to check if the constant exists in %s on line %d bool(false) Reflecting on instance of class D: string(12) "hello from C" + +Deprecated: ReflectionClass::getConstant() for a non-existent constant is deprecated, use ReflectionClass::hasConstant() to check if the constant exists in %s on line %d bool(false) Reflecting on instance of class E: string(12) "hello from C" + +Deprecated: ReflectionClass::getConstant() for a non-existent constant is deprecated, use ReflectionClass::hasConstant() to check if the constant exists in %s on line %d bool(false) Reflecting on instance of class F: string(12) "hello from F" + +Deprecated: ReflectionClass::getConstant() for a non-existent constant is deprecated, use ReflectionClass::hasConstant() to check if the constant exists in %s on line %d bool(false) Reflecting on instance of class X: + +Deprecated: ReflectionClass::getConstant() for a non-existent constant is deprecated, use ReflectionClass::hasConstant() to check if the constant exists in %s on line %d bool(false) + +Deprecated: ReflectionClass::getConstant() for a non-existent constant is deprecated, use ReflectionClass::hasConstant() to check if the constant exists in %s on line %d bool(false) diff --git a/ext/reflection/tests/ReflectionProperty_getDefaultValue.phpt b/ext/reflection/tests/ReflectionProperty_getDefaultValue.phpt index 423edfe9faf..d74e1f4bfe6 100644 --- a/ext/reflection/tests/ReflectionProperty_getDefaultValue.phpt +++ b/ext/reflection/tests/ReflectionProperty_getDefaultValue.phpt @@ -60,15 +60,21 @@ $property = new ReflectionProperty($test, 'dynamic'); var_dump($property->getDefaultValue()); ?> ---EXPECT-- +--EXPECTF-- NULL string(3) "baz" NULL int(1234) + +Deprecated: ReflectionProperty::getDefaultValue() for a property without a default value is deprecated, use ReflectionProperty::hasDefaultValue() to check if the default value exists in %s on line %d NULL int(1234) + +Deprecated: ReflectionProperty::getDefaultValue() for a property without a default value is deprecated, use ReflectionProperty::hasDefaultValue() to check if the default value exists in %s on line %d NULL NULL int(4) int(42) + +Deprecated: ReflectionProperty::getDefaultValue() for a property without a default value is deprecated, use ReflectionProperty::hasDefaultValue() to check if the default value exists in %s on line %d NULL diff --git a/ext/reflection/tests/ReflectionProperty_getMangledName_basic.phpt b/ext/reflection/tests/ReflectionProperty_getMangledName_basic.phpt new file mode 100644 index 00000000000..473ac2c84b8 --- /dev/null +++ b/ext/reflection/tests/ReflectionProperty_getMangledName_basic.phpt @@ -0,0 +1,43 @@ +--TEST-- +Test ReflectionProperty::getMangledName() method +--FILE-- +getName() . "\n"; + echo "getMangledName(): " . $reflection->getMangledName() . "\n"; + + $obj = new $class(); + $array = (array) $obj; + echo "In array cast: " . (array_key_exists($reflection->getMangledName(), $array) ? "found" : "not found") . "\n"; + echo "\n"; +} + +testMangledName('TestClass', 'publicProp'); +testMangledName('TestClass', 'protectedProp'); +testMangledName('TestClass', 'privateProp'); + +?> +--EXPECTF-- +Property: publicProp +getName(): publicProp +getMangledName(): publicProp +In array cast: found + +Property: protectedProp +getName(): protectedProp +getMangledName(): %0*%0protectedProp +In array cast: found + +Property: privateProp +getName(): privateProp +getMangledName(): %0TestClass%0privateProp +In array cast: found diff --git a/ext/reflection/tests/ReflectionProperty_getMangledName_dynamic.phpt b/ext/reflection/tests/ReflectionProperty_getMangledName_dynamic.phpt new file mode 100644 index 00000000000..271552ab46a --- /dev/null +++ b/ext/reflection/tests/ReflectionProperty_getMangledName_dynamic.phpt @@ -0,0 +1,125 @@ +--TEST-- +Test ReflectionProperty::getMangledName() with dynamic properties +--FILE-- +prop1 = 'value1'; +$stdObj->{'special-name'} = 'special value'; +$stdObj->{'123numeric'} = 'numeric start'; + +function testDynamicProperty($obj, $property, $description) { + try { + $reflection = new ReflectionProperty($obj, $property); + echo "$description:\n"; + echo " getName(): " . $reflection->getName() . "\n"; + echo " getMangledName(): " . $reflection->getMangledName() . "\n"; + + $array = (array) $obj; + echo " Found in array cast: " . (array_key_exists($reflection->getMangledName(), $array) ? "yes" : "no") . "\n"; + echo "\n"; + } catch (ReflectionException $e) { + echo "$description: EXCEPTION - " . $e->getMessage() . "\n\n"; + } +} + +testDynamicProperty($stdObj, 'prop1', 'stdClass property prop1'); +testDynamicProperty($stdObj, 'special-name', 'stdClass property with special name'); +testDynamicProperty($stdObj, '123numeric', 'stdClass property starting with number'); + +echo "=== Testing edge cases ===\n"; +$numericObj = (object)[true]; +testDynamicProperty($numericObj, '0', 'Property name as number'); + +$nullByteObj = (object)["foo\0" => true]; +testDynamicProperty($nullByteObj, "foo\0", 'Property name with null byte'); + +$invalidObj = (object)["::" => true]; +testDynamicProperty($invalidObj, '::', 'Invalid property name'); + +echo "=== Testing regular class with dynamic properties ===\n"; +#[AllowDynamicProperties] +class TestClass { + public $existing = 'existing'; +} + +$obj = new TestClass(); +$obj->dynamic = 'dynamic value'; +$obj->anotherDynamic = 'another dynamic'; + +testDynamicProperty($obj, 'dynamic', 'Regular class dynamic property'); +testDynamicProperty($obj, 'anotherDynamic', 'Regular class another dynamic property'); + +$reflection = new ReflectionProperty($obj, 'existing'); +echo "Regular property:\n"; +echo " getName(): " . $reflection->getName() . "\n"; +echo " getMangledName(): " . $reflection->getMangledName() . "\n"; + +echo "\n=== Testing ReflectionProperty from class vs instance ===\n"; +try { + $reflection = new ReflectionProperty('TestClass', 'dynamic'); + echo "This should not be reached\n"; +} catch (ReflectionException $e) { + echo "Expected exception for class-based reflection: " . $e->getMessage() . "\n"; +} + +try { + $reflection = new ReflectionProperty($obj, 'dynamic'); + echo "Instance-based reflection works: " . $reflection->getMangledName() . "\n"; +} catch (ReflectionException $e) { + echo "Unexpected exception: " . $e->getMessage() . "\n"; +} + +?> +--EXPECTF-- +=== Testing stdClass with dynamic properties === +stdClass property prop1: + getName(): prop1 + getMangledName(): prop1 + Found in array cast: yes + +stdClass property with special name: + getName(): special-name + getMangledName(): special-name + Found in array cast: yes + +stdClass property starting with number: + getName(): 123numeric + getMangledName(): 123numeric + Found in array cast: yes + +=== Testing edge cases === +Property name as number: + getName(): 0 + getMangledName(): 0 + Found in array cast: yes + +Property name with null byte: + getName(): foo%0 + getMangledName(): foo%0 + Found in array cast: yes + +Invalid property name: + getName(): :: + getMangledName(): :: + Found in array cast: yes + +=== Testing regular class with dynamic properties === +Regular class dynamic property: + getName(): dynamic + getMangledName(): dynamic + Found in array cast: yes + +Regular class another dynamic property: + getName(): anotherDynamic + getMangledName(): anotherDynamic + Found in array cast: yes + +Regular property: + getName(): existing + getMangledName(): existing + +=== Testing ReflectionProperty from class vs instance === +Expected exception for class-based reflection: Property TestClass::$dynamic does not exist +Instance-based reflection works: dynamic diff --git a/ext/reflection/tests/ReflectionProperty_getMangledName_hooks.phpt b/ext/reflection/tests/ReflectionProperty_getMangledName_hooks.phpt new file mode 100644 index 00000000000..da00a0da291 --- /dev/null +++ b/ext/reflection/tests/ReflectionProperty_getMangledName_hooks.phpt @@ -0,0 +1,82 @@ +--TEST-- +Test ReflectionProperty::getMangledName() with property hooks +--FILE-- + "virtual"; + } + + public string $bar { + get => "hooked getter"; + set => throw new Exception("Cannot set bar"); + } + + public string $baz = "backed"; +} + +$d = new Demo(); + +function testHookedProperty($obj, $property, $description) { + try { + $reflection = new ReflectionProperty($obj, $property); + echo "$description:\n"; + echo " getName(): " . $reflection->getName() . "\n"; + echo " getMangledName(): " . $reflection->getMangledName() . "\n"; + + $array = (array) $obj; + echo " Found in array cast: " . (array_key_exists($reflection->getMangledName(), $array) ? "yes" : "no") . "\n"; + echo " Has hooks: " . ($reflection->hasHooks() ? "yes" : "no") . "\n"; + echo "\n"; + } catch (ReflectionException $e) { + echo "$description: EXCEPTION - " . $e->getMessage() . "\n\n"; + } +} + +testHookedProperty($d, 'foo', 'Virtual hooked property (protected)'); +testHookedProperty($d, 'bar', 'Hooked property with getter/setter (public)'); +testHookedProperty($d, 'baz', 'Regular backed property'); + +echo "=== Object dump ===\n"; +var_dump($d); + +echo "\n=== Array cast ===\n"; +var_dump((array)$d); + +?> +--EXPECTF-- +=== Testing virtual hooked properties === +Virtual hooked property (protected): + getName(): foo + getMangledName(): %0*%0foo + Found in array cast: no + Has hooks: yes + +Hooked property with getter/setter (public): + getName(): bar + getMangledName(): bar + Found in array cast: no + Has hooks: yes + +Regular backed property: + getName(): baz + getMangledName(): baz + Found in array cast: yes + Has hooks: no + +=== Object dump === +object(Demo)#1 (1) { + ["bar"]=> + uninitialized(string) + ["baz"]=> + string(6) "backed" +} + +=== Array cast === +array(1) { + ["baz"]=> + string(6) "backed" +} diff --git a/ext/reflection/tests/ReflectionProperty_getMangledName_inheritance.phpt b/ext/reflection/tests/ReflectionProperty_getMangledName_inheritance.phpt new file mode 100644 index 00000000000..301756c8cbf --- /dev/null +++ b/ext/reflection/tests/ReflectionProperty_getMangledName_inheritance.phpt @@ -0,0 +1,87 @@ +--TEST-- +Test ReflectionProperty::getMangledName() with inheritance +--FILE-- +getMangledName() . "'\n"; + echo "Key exists in array cast: " . (array_key_exists($reflection->getMangledName(), $array) ? "yes" : "no") . "\n"; + echo "\n"; +} + +testProperty('ParentClass', 'public'); +testProperty('ParentClass', 'protected'); +testProperty('ParentClass', 'private'); + +testProperty('ChildClass', 'public'); +testProperty('ChildClass', 'protected'); +testProperty('ChildClass', 'childProp'); +testProperty('ChildClass', 'private'); + +echo "Access to parent's private property not in child:\n"; + +try { + $reflection = new ReflectionProperty('ChildClass', 'parentOnly'); + echo "ERROR: Should have failed\n"; +} catch (ReflectionException $e) { + echo "Instance-based creation failed as expected: " . $e->getMessage() . "\n"; +} + +try { + $obj = new ChildClass(); + $reflection = new ReflectionProperty($obj, 'parentOnly'); + echo "ERROR: Should have failed\n"; +} catch (ReflectionException $e) { + echo "Object-based creation failed as expected: " . $e->getMessage() . "\n"; +} + +?> +--EXPECTF-- +Class: ParentClass, Property: $public +Mangled name: 'public' +Key exists in array cast: yes + +Class: ParentClass, Property: $protected +Mangled name: '%0*%0protected' +Key exists in array cast: yes + +Class: ParentClass, Property: $private +Mangled name: '%0ParentClass%0private' +Key exists in array cast: yes + +Class: ChildClass, Property: $public +Mangled name: 'public' +Key exists in array cast: yes + +Class: ChildClass, Property: $protected +Mangled name: '%0*%0protected' +Key exists in array cast: yes + +Class: ChildClass, Property: $childProp +Mangled name: '%0*%0childProp' +Key exists in array cast: yes + +Class: ChildClass, Property: $private +Mangled name: '%0ChildClass%0private' +Key exists in array cast: yes + +Access to parent's private property not in child: +Instance-based creation failed as expected: Property ChildClass::$parentOnly does not exist +Object-based creation failed as expected: Property ChildClass::$parentOnly does not exist diff --git a/ext/reflection/tests/ReflectionProperty_getMangledName_instance.phpt b/ext/reflection/tests/ReflectionProperty_getMangledName_instance.phpt new file mode 100644 index 00000000000..7c24ce85f17 --- /dev/null +++ b/ext/reflection/tests/ReflectionProperty_getMangledName_instance.phpt @@ -0,0 +1,99 @@ +--TEST-- +Test ReflectionProperty::getMangledName() from instance vs class +--FILE-- +dynamic = 'dynamic'; + +echo "=== Testing ReflectionProperty from CLASS ===\n"; + +function testFromClass($property) { + try { + $reflection = new ReflectionProperty('TestClass', $property); + echo "Property $property from class:\n"; + echo " getName(): " . $reflection->getName() . "\n"; + echo " getMangledName(): " . $reflection->getMangledName() . "\n"; + echo "\n"; + } catch (ReflectionException $e) { + echo "Property $property from class: EXCEPTION - " . $e->getMessage() . "\n\n"; + } +} + +testFromClass('public'); +testFromClass('protected'); +testFromClass('private'); +testFromClass('dynamic'); + +echo "=== Testing ReflectionProperty from INSTANCE ===\n"; + +function testFromInstance($obj, $property) { + try { + $reflection = new ReflectionProperty($obj, $property); + echo "Property $property from instance:\n"; + echo " getName(): " . $reflection->getName() . "\n"; + echo " getMangledName(): " . $reflection->getMangledName() . "\n"; + + $array = (array) $obj; + echo " Found in array cast: " . (array_key_exists($reflection->getMangledName(), $array) ? "yes" : "no") . "\n"; + echo "\n"; + } catch (ReflectionException $e) { + echo "Property $property from instance: EXCEPTION - " . $e->getMessage() . "\n\n"; + } +} + +testFromInstance($obj, 'public'); +testFromInstance($obj, 'protected'); +testFromInstance($obj, 'private'); + +echo "=== Instance array keys ===\n"; +$array = (array) $obj; +foreach (array_keys($array) as $key) { + echo "Key: '$key'\n"; +} + +?> +--EXPECTF-- +=== Testing ReflectionProperty from CLASS === +Property public from class: + getName(): public + getMangledName(): public + +Property protected from class: + getName(): protected + getMangledName(): %0*%0protected + +Property private from class: + getName(): private + getMangledName(): %0TestClass%0private + +Property dynamic from class: EXCEPTION - Property TestClass::$dynamic does not exist + +=== Testing ReflectionProperty from INSTANCE === +Property public from instance: + getName(): public + getMangledName(): public + Found in array cast: yes + +Property protected from instance: + getName(): protected + getMangledName(): %0*%0protected + Found in array cast: yes + +Property private from instance: + getName(): private + getMangledName(): %0TestClass%0private + Found in array cast: yes + +=== Instance array keys === +Key: 'public' +Key: '%0*%0protected' +Key: '%0TestClass%0private' +Key: 'dynamic' diff --git a/ext/reflection/tests/ReflectionProperty_getMangledName_override.phpt b/ext/reflection/tests/ReflectionProperty_getMangledName_override.phpt new file mode 100644 index 00000000000..3f6a3bfdcc5 --- /dev/null +++ b/ext/reflection/tests/ReflectionProperty_getMangledName_override.phpt @@ -0,0 +1,123 @@ +--TEST-- +Test ReflectionProperty::getMangledName() with property overrides and visibility changes +--FILE-- +getName() . "\n"; + echo " getMangledName(): " . $reflection->getMangledName() . "\n"; + echo " Visibility: " . ($reflection->isPublic() ? 'public' : ($reflection->isProtected() ? 'protected' : 'private')) . "\n"; + + $obj = new $class(); + $array = (array) $obj; + echo " Found in array cast: " . (array_key_exists($reflection->getMangledName(), $array) ? "yes" : "no") . "\n"; + echo "\n"; +} + +testPropertyOverride('Parent1', 'prop', 'Parent public property'); +testPropertyOverride('Child1', 'prop', 'Child public property (overrides parent public)'); + +testPropertyOverride('Parent1', 'protectedProp', 'Parent protected property'); +testPropertyOverride('Child1', 'protectedProp', 'Child public property (overrides parent protected)'); + +testPropertyOverride('Parent2', 'visibilityTest', 'Parent protected property'); +testPropertyOverride('Child2', 'visibilityTest', 'Child public property (overrides parent protected)'); + +testPropertyOverride('Parent1', 'privateProp', 'Parent private property'); + +echo "Child1 instance array keys:\n"; +$child1 = new Child1(); +$array = (array) $child1; +foreach (array_keys($array) as $key) { + echo " '$key'\n"; +} + +?> +--EXPECTF-- +Parent public property: + Class: Parent1 + Property: prop + getName(): prop + getMangledName(): prop + Visibility: public + Found in array cast: yes + +Child public property (overrides parent public): + Class: Child1 + Property: prop + getName(): prop + getMangledName(): prop + Visibility: public + Found in array cast: yes + +Parent protected property: + Class: Parent1 + Property: protectedProp + getName(): protectedProp + getMangledName(): %0*%0protectedProp + Visibility: protected + Found in array cast: yes + +Child public property (overrides parent protected): + Class: Child1 + Property: protectedProp + getName(): protectedProp + getMangledName(): protectedProp + Visibility: public + Found in array cast: yes + +Parent protected property: + Class: Parent2 + Property: visibilityTest + getName(): visibilityTest + getMangledName(): %0*%0visibilityTest + Visibility: protected + Found in array cast: yes + +Child public property (overrides parent protected): + Class: Child2 + Property: visibilityTest + getName(): visibilityTest + getMangledName(): visibilityTest + Visibility: public + Found in array cast: yes + +Parent private property: + Class: Parent1 + Property: privateProp + getName(): privateProp + getMangledName(): %0Parent1%0privateProp + Visibility: private + Found in array cast: yes + +Child1 instance array keys: + 'prop' + 'protectedProp' + '%0Parent1%0privateProp' diff --git a/ext/reflection/tests/ReflectionProperty_setAccessible.phpt b/ext/reflection/tests/ReflectionProperty_setAccessible.phpt index 4e12af87916..b63ab38c159 100644 --- a/ext/reflection/tests/ReflectionProperty_setAccessible.phpt +++ b/ext/reflection/tests/ReflectionProperty_setAccessible.phpt @@ -95,6 +95,14 @@ string(1) "e" string(1) "f" string(1) "g" string(1) "h" + +Deprecated: Method ReflectionProperty::setAccessible() is deprecated since 8.5, as it has no effect in %s on line %d + +Deprecated: Method ReflectionProperty::setAccessible() is deprecated since 8.5, as it has no effect in %s on line %d + +Deprecated: Method ReflectionProperty::setAccessible() is deprecated since 8.5, as it has no effect in %s on line %d + +Deprecated: Method ReflectionProperty::setAccessible() is deprecated since 8.5, as it has no effect in %s on line %d string(1) "e" string(1) "f" string(1) "g" @@ -111,6 +119,12 @@ string(1) "c" string(1) "e" string(1) "f" string(1) "g" + +Deprecated: Method ReflectionProperty::setAccessible() is deprecated since 8.5, as it has no effect in %s on line %d + +Deprecated: Method ReflectionProperty::setAccessible() is deprecated since 8.5, as it has no effect in %s on line %d + +Deprecated: Method ReflectionProperty::setAccessible() is deprecated since 8.5, as it has no effect in %s on line %d string(1) "e" string(1) "f" string(1) "g" diff --git a/ext/reflection/tests/ReflectionProperty_toString_001.phpt b/ext/reflection/tests/ReflectionProperty_toString_001.phpt new file mode 100644 index 00000000000..0af0283bb50 --- /dev/null +++ b/ext/reflection/tests/ReflectionProperty_toString_001.phpt @@ -0,0 +1,89 @@ +--TEST-- +Using ReflectionProperty::__toString() with hooked properties (GH-17927) +--FILE-- + "always this string"; + } + public mixed $setOnly { + set => strtolower($value); + } + public mixed $both { + get => $this->prop3; + set => strtolower($value); + } +} +class WithFinalHooks { + public mixed $getOnly { + final get => "always this string"; + } + public mixed $setOnly { + final set => strtolower($value); + } + public mixed $both { + final get => $this->prop3; + final set => strtolower($value); + } +} +class WithMixedHooks { + public mixed $getIsFinal { + final get => "always this string"; + set => strtolower($value); + } + public mixed $setIsFinal { + get => $this->setIsFinal; + final set => strtolower($value); + } +} +$classes = [ + IHookedDemo::class, + HookedDemo::class, + WithHooks::class, + WithFinalHooks::class, + WithMixedHooks::class, +]; +foreach ( $classes as $clazz ) { + echo "$clazz:\n"; + $ref = new ReflectionClass( $clazz ); + foreach ( $ref->getProperties() as $prop ) { + echo $prop; + } + echo "\n"; +} +?> +--EXPECT-- +IHookedDemo: +Property [ abstract public virtual mixed $getOnly { get; } ] +Property [ abstract public virtual mixed $setOnly { set; } ] +Property [ abstract public virtual mixed $both { get; set; } ] + +HookedDemo: +Property [ abstract public virtual mixed $getOnly { get; } ] +Property [ abstract public virtual mixed $setOnly { set; } ] +Property [ abstract public virtual mixed $both { get; set; } ] + +WithHooks: +Property [ public virtual mixed $getOnly { get; } ] +Property [ public mixed $setOnly { set; } ] +Property [ public mixed $both { get; set; } ] + +WithFinalHooks: +Property [ public virtual mixed $getOnly { final get; } ] +Property [ public mixed $setOnly { final set; } ] +Property [ public mixed $both { final get; final set; } ] + +WithMixedHooks: +Property [ public mixed $getIsFinal { final get; set; } ] +Property [ public mixed $setIsFinal { get; final set; } ] diff --git a/ext/reflection/tests/abstract_property_indicated.phpt b/ext/reflection/tests/abstract_property_indicated.phpt index a70d88b7ece..23866be890d 100644 --- a/ext/reflection/tests/abstract_property_indicated.phpt +++ b/ext/reflection/tests/abstract_property_indicated.phpt @@ -31,12 +31,12 @@ Class [ abstract class Demo ] { } - Properties [2] { - Property [ abstract public $a ] + Property [ abstract public virtual $a { get; } ] Property [ public $b = NULL ] } - Methods [0] { } } -Property [ abstract public $a ] +Property [ abstract public virtual $a { get; } ] Property [ public $b = NULL ] diff --git a/ext/reflection/tests/bug38653.phpt b/ext/reflection/tests/bug38653.phpt index 36504e7c7b6..e166546eeb9 100644 --- a/ext/reflection/tests/bug38653.phpt +++ b/ext/reflection/tests/bug38653.phpt @@ -20,9 +20,11 @@ var_dump($foo->getConstant("no such const")); echo "Done\n"; ?> ---EXPECT-- +--EXPECTF-- int(10) string(0) "" string(4) "test" + +Deprecated: ReflectionClass::getConstant() for a non-existent constant is deprecated, use ReflectionClass::hasConstant() to check if the constant exists in %s on line %d bool(false) Done diff --git a/ext/reflection/tests/bug79683.phpt b/ext/reflection/tests/bug79683.phpt index 766571918af..4eeafb6bb93 100644 --- a/ext/reflection/tests/bug79683.phpt +++ b/ext/reflection/tests/bug79683.phpt @@ -22,7 +22,6 @@ $b = new B(); $reflector = new ReflectionClass($b); $property = $reflector->getProperty('prop2'); -$property->setAccessible(true); $property->setValue($b, new A()); var_dump($b); diff --git a/ext/reflection/tests/gh19187.phpt b/ext/reflection/tests/gh19187.phpt new file mode 100644 index 00000000000..35a684aa6af --- /dev/null +++ b/ext/reflection/tests/gh19187.phpt @@ -0,0 +1,56 @@ +--TEST-- +GH-19187: ReflectionNamedType::getName() should not include nullable type +--FILE-- + $value; + } + public string|null $b { + set(string|null $value) => $value; + } + public string|null $c { + get => $this->c; + } +} + +foreach ((new ReflectionClass(C::class))->getProperties() as $r) { + $type = $r->getType(); + echo $type, "\n"; + echo $type->getName(), "\n"; + var_dump($type->allowsNull()); + echo "\n"; + + $settableType = $r->getSettableType(); + echo $settableType, "\n"; + echo $settableType->getName(), "\n"; + var_dump($settableType->allowsNull()); + echo "\n"; +} + +?> +--EXPECT-- +?string +string +bool(true) + +?string +string +bool(true) + +?string +string +bool(true) + +?string +string +bool(true) + +?string +string +bool(true) + +?string +string +bool(true) diff --git a/ext/reflection/tests/property_hooks/basics.phpt b/ext/reflection/tests/property_hooks/basics.phpt index 8c363dcc4bf..6011018c64c 100644 --- a/ext/reflection/tests/property_hooks/basics.phpt +++ b/ext/reflection/tests/property_hooks/basics.phpt @@ -47,7 +47,6 @@ try { } catch (ReflectionException $e) { echo $e->getMessage(), "\n"; } -$s->setAccessible(true); $s->invoke($test, 42); var_dump($test->prop2); dumpFlags($rp2); diff --git a/ext/session/php_session.h b/ext/session/php_session.h index 8a0d2ed27b8..e48ed461529 100644 --- a/ext/session/php_session.h +++ b/ext/session/php_session.h @@ -149,6 +149,7 @@ typedef struct _php_ps_globals { zend_string *cookie_samesite; bool cookie_secure; bool cookie_httponly; + bool cookie_partitioned; const ps_module *mod; const ps_module *default_mod; void *mod_data; diff --git a/ext/session/session.c b/ext/session/session.c index 33cc6cd4b7d..fa522702792 100644 --- a/ext/session/session.c +++ b/ext/session/session.c @@ -886,30 +886,31 @@ static PHP_INI_MH(OnUpdateRefererCheck) } PHP_INI_BEGIN() - STD_PHP_INI_ENTRY("session.save_path", "", PHP_INI_ALL, OnUpdateSaveDir, save_path, php_ps_globals, ps_globals) - STD_PHP_INI_ENTRY("session.name", "PHPSESSID", PHP_INI_ALL, OnUpdateName, session_name, php_ps_globals, ps_globals) - PHP_INI_ENTRY("session.save_handler", "files", PHP_INI_ALL, OnUpdateSaveHandler) - STD_PHP_INI_BOOLEAN("session.auto_start", "0", PHP_INI_PERDIR, OnUpdateBool, auto_start, php_ps_globals, ps_globals) - STD_PHP_INI_ENTRY("session.gc_probability", "1", PHP_INI_ALL, OnUpdateSessionGcProbability, gc_probability, php_ps_globals, ps_globals) - STD_PHP_INI_ENTRY("session.gc_divisor", "100", PHP_INI_ALL, OnUpdateSessionDivisor,gc_divisor, php_ps_globals, ps_globals) - STD_PHP_INI_ENTRY("session.gc_maxlifetime", "1440", PHP_INI_ALL, OnUpdateSessionLong, gc_maxlifetime, php_ps_globals, ps_globals) - PHP_INI_ENTRY("session.serialize_handler", "php", PHP_INI_ALL, OnUpdateSerializer) - STD_PHP_INI_ENTRY("session.cookie_lifetime", "0", PHP_INI_ALL, OnUpdateCookieLifetime,cookie_lifetime, php_ps_globals, ps_globals) - STD_PHP_INI_ENTRY("session.cookie_path", "/", PHP_INI_ALL, OnUpdateSessionStr, cookie_path, php_ps_globals, ps_globals) - STD_PHP_INI_ENTRY("session.cookie_domain", "", PHP_INI_ALL, OnUpdateSessionStr, cookie_domain, php_ps_globals, ps_globals) - STD_PHP_INI_BOOLEAN("session.cookie_secure", "0", PHP_INI_ALL, OnUpdateSessionBool, cookie_secure, php_ps_globals, ps_globals) - STD_PHP_INI_BOOLEAN("session.cookie_httponly", "0", PHP_INI_ALL, OnUpdateSessionBool, cookie_httponly, php_ps_globals, ps_globals) - STD_PHP_INI_ENTRY("session.cookie_samesite", "", PHP_INI_ALL, OnUpdateSessionStr, cookie_samesite, php_ps_globals, ps_globals) - STD_PHP_INI_BOOLEAN("session.use_cookies", "1", PHP_INI_ALL, OnUpdateSessionBool, use_cookies, php_ps_globals, ps_globals) - STD_PHP_INI_BOOLEAN("session.use_only_cookies", "1", PHP_INI_ALL, OnUpdateUseOnlyCookies, use_only_cookies, php_ps_globals, ps_globals) - STD_PHP_INI_BOOLEAN("session.use_strict_mode", "0", PHP_INI_ALL, OnUpdateSessionBool, use_strict_mode, php_ps_globals, ps_globals) - STD_PHP_INI_ENTRY("session.referer_check", "", PHP_INI_ALL, OnUpdateRefererCheck, extern_referer_chk, php_ps_globals, ps_globals) - STD_PHP_INI_ENTRY("session.cache_limiter", "nocache", PHP_INI_ALL, OnUpdateSessionStr, cache_limiter, php_ps_globals, ps_globals) - STD_PHP_INI_ENTRY("session.cache_expire", "180", PHP_INI_ALL, OnUpdateSessionLong, cache_expire, php_ps_globals, ps_globals) - STD_PHP_INI_BOOLEAN("session.use_trans_sid", "0", PHP_INI_ALL, OnUpdateUseTransSid, use_trans_sid, php_ps_globals, ps_globals) - PHP_INI_ENTRY("session.sid_length", "32", PHP_INI_ALL, OnUpdateSidLength) - PHP_INI_ENTRY("session.sid_bits_per_character", "4", PHP_INI_ALL, OnUpdateSidBits) - STD_PHP_INI_BOOLEAN("session.lazy_write", "1", PHP_INI_ALL, OnUpdateSessionBool, lazy_write, php_ps_globals, ps_globals) + STD_PHP_INI_ENTRY("session.save_path", "", PHP_INI_ALL, OnUpdateSaveDir, save_path, php_ps_globals, ps_globals) + STD_PHP_INI_ENTRY("session.name", "PHPSESSID", PHP_INI_ALL, OnUpdateName, session_name, php_ps_globals, ps_globals) + PHP_INI_ENTRY("session.save_handler", "files", PHP_INI_ALL, OnUpdateSaveHandler) + STD_PHP_INI_BOOLEAN("session.auto_start", "0", PHP_INI_PERDIR, OnUpdateBool, auto_start, php_ps_globals, ps_globals) + STD_PHP_INI_ENTRY("session.gc_probability", "1", PHP_INI_ALL, OnUpdateSessionGcProbability, gc_probability, php_ps_globals, ps_globals) + STD_PHP_INI_ENTRY("session.gc_divisor", "100", PHP_INI_ALL, OnUpdateSessionDivisor, gc_divisor, php_ps_globals, ps_globals) + STD_PHP_INI_ENTRY("session.gc_maxlifetime", "1440", PHP_INI_ALL, OnUpdateSessionLong, gc_maxlifetime, php_ps_globals, ps_globals) + PHP_INI_ENTRY("session.serialize_handler", "php", PHP_INI_ALL, OnUpdateSerializer) + STD_PHP_INI_ENTRY("session.cookie_lifetime", "0", PHP_INI_ALL, OnUpdateCookieLifetime, cookie_lifetime, php_ps_globals, ps_globals) + STD_PHP_INI_ENTRY("session.cookie_path", "/", PHP_INI_ALL, OnUpdateSessionStr, cookie_path, php_ps_globals, ps_globals) + STD_PHP_INI_ENTRY("session.cookie_domain", "", PHP_INI_ALL, OnUpdateSessionStr, cookie_domain, php_ps_globals, ps_globals) + STD_PHP_INI_BOOLEAN("session.cookie_secure", "0", PHP_INI_ALL, OnUpdateSessionBool, cookie_secure, php_ps_globals, ps_globals) + STD_PHP_INI_BOOLEAN("session.cookie_partitioned", "0", PHP_INI_ALL, OnUpdateSessionBool, cookie_partitioned, php_ps_globals, ps_globals) + STD_PHP_INI_BOOLEAN("session.cookie_httponly", "0", PHP_INI_ALL, OnUpdateSessionBool, cookie_httponly, php_ps_globals, ps_globals) + STD_PHP_INI_ENTRY("session.cookie_samesite", "", PHP_INI_ALL, OnUpdateSessionStr, cookie_samesite, php_ps_globals, ps_globals) + STD_PHP_INI_BOOLEAN("session.use_cookies", "1", PHP_INI_ALL, OnUpdateSessionBool, use_cookies, php_ps_globals, ps_globals) + STD_PHP_INI_BOOLEAN("session.use_only_cookies", "1", PHP_INI_ALL, OnUpdateUseOnlyCookies, use_only_cookies, php_ps_globals, ps_globals) + STD_PHP_INI_BOOLEAN("session.use_strict_mode", "0", PHP_INI_ALL, OnUpdateSessionBool, use_strict_mode, php_ps_globals, ps_globals) + STD_PHP_INI_ENTRY("session.referer_check", "", PHP_INI_ALL, OnUpdateRefererCheck, extern_referer_chk, php_ps_globals, ps_globals) + STD_PHP_INI_ENTRY("session.cache_limiter", "nocache", PHP_INI_ALL, OnUpdateSessionStr, cache_limiter, php_ps_globals, ps_globals) + STD_PHP_INI_ENTRY("session.cache_expire", "180", PHP_INI_ALL, OnUpdateSessionLong, cache_expire, php_ps_globals, ps_globals) + STD_PHP_INI_BOOLEAN("session.use_trans_sid", "0", PHP_INI_ALL, OnUpdateUseTransSid, use_trans_sid, php_ps_globals, ps_globals) + PHP_INI_ENTRY("session.sid_length", "32", PHP_INI_ALL, OnUpdateSidLength) + PHP_INI_ENTRY("session.sid_bits_per_character", "4", PHP_INI_ALL, OnUpdateSidBits) + STD_PHP_INI_BOOLEAN("session.lazy_write", "1", PHP_INI_ALL, OnUpdateSessionBool, lazy_write, php_ps_globals, ps_globals) /* Upload progress */ STD_PHP_INI_BOOLEAN("session.upload_progress.enabled", @@ -1246,7 +1247,7 @@ static inline void last_modified(void) } #define LAST_MODIFIED "Last-Modified: " - memcpy(buf, ZEND_STRL(LAST_MODIFIED)); + memcpy(buf, LAST_MODIFIED, sizeof(LAST_MODIFIED) - 1); strcpy_gmt(buf + sizeof(LAST_MODIFIED) - 1, &sb.st_mtime); ADD_HEADER(buf); } @@ -1261,7 +1262,7 @@ CACHE_LIMITER_FUNC(public) gettimeofday(&tv, NULL); now = tv.tv_sec + PS(cache_expire) * 60; - memcpy(buf, ZEND_STRL(EXPIRES)); + memcpy(buf, EXPIRES, sizeof(EXPIRES) - 1); strcpy_gmt(buf + sizeof(EXPIRES) - 1, &now); ADD_HEADER(buf); @@ -1335,45 +1336,19 @@ static int php_session_cache_limiter(void) * Cookie Management * ********************* */ -/* - * Remove already sent session ID cookie. - * It must be directly removed from SG(sapi_header) because sapi_add_header_ex() - * removes all of matching cookie. i.e. It deletes all of Set-Cookie headers. - */ static void php_session_remove_cookie(void) { - sapi_header_struct *header; - zend_llist *l = &SG(sapi_headers).headers; - zend_llist_element *next; - zend_llist_element *current; char *session_cookie; size_t session_cookie_len; - size_t len = sizeof("Set-Cookie")-1; + sapi_header_line header_line = {0}; ZEND_ASSERT(strpbrk(ZSTR_VAL(PS(session_name)), SESSION_FORBIDDEN_CHARS) == NULL); session_cookie_len = spprintf(&session_cookie, 0, "Set-Cookie: %s=", ZSTR_VAL(PS(session_name))); - current = l->head; - while (current) { - header = (sapi_header_struct *)(current->data); - next = current->next; - if (header->header_len > len && header->header[len] == ':' - && !strncmp(header->header, session_cookie, session_cookie_len)) { - if (current->prev) { - current->prev->next = next; - } else { - l->head = next; - } - if (next) { - next->prev = current->prev; - } else { - l->tail = current->prev; - } - sapi_free_header(header); - efree(current); - --l->count; - } - current = next; - } + header_line.line = session_cookie; + header_line.line_len = session_cookie_len; + header_line.header_len = sizeof("Set-Cookie") - 1; + sapi_header_op(SAPI_HEADER_DELETE_PREFIX, &header_line); + efree(session_cookie); } @@ -1388,6 +1363,12 @@ static zend_result php_session_send_cookie(void) return FAILURE; } + /* Check for invalid settings combinations */ + if (UNEXPECTED(PS(cookie_partitioned) && !PS(cookie_secure))) { + php_error_docref(NULL, E_WARNING, "Partitioned session cookie cannot be used without also configuring it as secure"); + return FAILURE; + } + ZEND_ASSERT(strpbrk(ZSTR_VAL(PS(session_name)), SESSION_FORBIDDEN_CHARS) == NULL); /* URL encode id because it might be user supplied */ @@ -1432,6 +1413,10 @@ static zend_result php_session_send_cookie(void) smart_str_appends(&ncookie, COOKIE_SECURE); } + if (PS(cookie_partitioned)) { + smart_str_appends(&ncookie, COOKIE_PARTITIONED); + } + if (PS(cookie_httponly)) { smart_str_appends(&ncookie, COOKIE_HTTPONLY); } @@ -1725,6 +1710,7 @@ PHP_FUNCTION(session_set_cookie_params) zend_string *lifetime = NULL, *path = NULL, *domain = NULL, *samesite = NULL; bool secure = 0, secure_null = 1; bool httponly = 0, httponly_null = 1; + bool partitioned = false, partitioned_null = true; zend_string *ini_name; zend_result result; int found = 0; @@ -1792,6 +1778,10 @@ PHP_FUNCTION(session_set_cookie_params) secure = zval_is_true(value); secure_null = 0; found++; + } else if (zend_string_equals_literal_ci(key, "partitioned")) { + partitioned = zval_is_true(value); + partitioned_null = 0; + found++; } else if (zend_string_equals_literal_ci(key, "httponly")) { httponly = zval_is_true(value); httponly_null = 0; @@ -1856,6 +1846,15 @@ PHP_FUNCTION(session_set_cookie_params) goto cleanup; } } + if (!partitioned_null) { + ini_name = ZSTR_INIT_LITERAL("session.cookie_partitioned", 0); + result = zend_alter_ini_entry_chars(ini_name, partitioned ? "1" : "0", 1, PHP_INI_USER, PHP_INI_STAGE_RUNTIME); + zend_string_release_ex(ini_name, 0); + if (result == FAILURE) { + RETVAL_FALSE; + goto cleanup; + } + } if (!httponly_null) { ini_name = ZSTR_INIT_LITERAL("session.cookie_httponly", 0); result = zend_alter_ini_entry_chars(ini_name, httponly ? "1" : "0", 1, PHP_INI_USER, PHP_INI_STAGE_RUNTIME); @@ -1898,6 +1897,7 @@ PHP_FUNCTION(session_get_cookie_params) add_assoc_str(return_value, "path", zend_string_dup(PS(cookie_path), false)); add_assoc_str(return_value, "domain", zend_string_dup(PS(cookie_domain), false)); add_assoc_bool(return_value, "secure", PS(cookie_secure)); + add_assoc_bool(return_value, "partitioned", PS(cookie_partitioned)); add_assoc_bool(return_value, "httponly", PS(cookie_httponly)); add_assoc_str(return_value, "samesite", zend_string_dup(PS(cookie_samesite), false)); } diff --git a/ext/session/tests/session_get_cookie_params_basic.phpt b/ext/session/tests/session_get_cookie_params_basic.phpt index 65b020d30b9..1c7cdf189fc 100644 --- a/ext/session/tests/session_get_cookie_params_basic.phpt +++ b/ext/session/tests/session_get_cookie_params_basic.phpt @@ -9,6 +9,7 @@ session.cookie_lifetime=0 session.cookie_path="/" session.cookie_domain="" session.cookie_secure=0 +session.cookie_partitioned=0 session.cookie_httponly=0 session.cookie_samesite="" --FILE-- @@ -31,13 +32,17 @@ var_dump(session_set_cookie_params([ "httponly" => FALSE, "samesite" => "please"])); var_dump(session_get_cookie_params()); +var_dump(session_set_cookie_params([ + "secure" => TRUE, + "partitioned" => TRUE])); +var_dump(session_get_cookie_params()); echo "Done"; ob_end_flush(); ?> --EXPECTF-- *** Testing session_get_cookie_params() : basic functionality *** -array(6) { +array(7) { ["lifetime"]=> int(0) ["path"]=> @@ -46,13 +51,15 @@ array(6) { string(0) "" ["secure"]=> bool(false) + ["partitioned"]=> + bool(false) ["httponly"]=> bool(false) ["samesite"]=> string(0) "" } bool(true) -array(6) { +array(7) { ["lifetime"]=> int(3600) ["path"]=> @@ -61,13 +68,15 @@ array(6) { string(4) "blah" ["secure"]=> bool(false) + ["partitioned"]=> + bool(false) ["httponly"]=> bool(false) ["samesite"]=> string(0) "" } bool(true) -array(6) { +array(7) { ["lifetime"]=> int(%d) ["path"]=> @@ -76,13 +85,15 @@ array(6) { string(3) "foo" ["secure"]=> bool(true) + ["partitioned"]=> + bool(false) ["httponly"]=> bool(true) ["samesite"]=> string(0) "" } bool(true) -array(6) { +array(7) { ["lifetime"]=> int(123) ["path"]=> @@ -91,6 +102,25 @@ array(6) { string(3) "baz" ["secure"]=> bool(false) + ["partitioned"]=> + bool(false) + ["httponly"]=> + bool(false) + ["samesite"]=> + string(6) "please" +} +bool(true) +array(7) { + ["lifetime"]=> + int(123) + ["path"]=> + string(4) "/bar" + ["domain"]=> + string(3) "baz" + ["secure"]=> + bool(true) + ["partitioned"]=> + bool(true) ["httponly"]=> bool(false) ["samesite"]=> diff --git a/ext/session/tests/session_get_cookie_params_variation1.phpt b/ext/session/tests/session_get_cookie_params_variation1.phpt index 4feb0d3ec81..7ce112c9b94 100644 --- a/ext/session/tests/session_get_cookie_params_variation1.phpt +++ b/ext/session/tests/session_get_cookie_params_variation1.phpt @@ -9,6 +9,7 @@ session.cookie_lifetime=0 session.cookie_path="/" session.cookie_domain="" session.cookie_secure=0 +session.cookie_partitioned=0 session.cookie_httponly=0 session.cookie_samesite="" --FILE-- @@ -31,13 +32,15 @@ ini_set("session.cookie_httponly", TRUE); var_dump(session_get_cookie_params()); ini_set("session.cookie_samesite", "foo"); var_dump(session_get_cookie_params()); +ini_set("session.cookie_partitioned", TRUE); +var_dump(session_get_cookie_params()); echo "Done"; ob_end_flush(); ?> --EXPECT-- *** Testing session_get_cookie_params() : variation *** -array(6) { +array(7) { ["lifetime"]=> int(0) ["path"]=> @@ -46,12 +49,14 @@ array(6) { string(0) "" ["secure"]=> bool(false) + ["partitioned"]=> + bool(false) ["httponly"]=> bool(false) ["samesite"]=> string(0) "" } -array(6) { +array(7) { ["lifetime"]=> int(3600) ["path"]=> @@ -60,12 +65,14 @@ array(6) { string(0) "" ["secure"]=> bool(false) + ["partitioned"]=> + bool(false) ["httponly"]=> bool(false) ["samesite"]=> string(0) "" } -array(6) { +array(7) { ["lifetime"]=> int(3600) ["path"]=> @@ -74,12 +81,14 @@ array(6) { string(0) "" ["secure"]=> bool(false) + ["partitioned"]=> + bool(false) ["httponly"]=> bool(false) ["samesite"]=> string(0) "" } -array(6) { +array(7) { ["lifetime"]=> int(3600) ["path"]=> @@ -88,12 +97,14 @@ array(6) { string(3) "foo" ["secure"]=> bool(false) + ["partitioned"]=> + bool(false) ["httponly"]=> bool(false) ["samesite"]=> string(0) "" } -array(6) { +array(7) { ["lifetime"]=> int(3600) ["path"]=> @@ -102,12 +113,14 @@ array(6) { string(3) "foo" ["secure"]=> bool(true) + ["partitioned"]=> + bool(false) ["httponly"]=> bool(false) ["samesite"]=> string(0) "" } -array(6) { +array(7) { ["lifetime"]=> int(3600) ["path"]=> @@ -116,12 +129,14 @@ array(6) { string(3) "foo" ["secure"]=> bool(true) + ["partitioned"]=> + bool(false) ["httponly"]=> bool(true) ["samesite"]=> string(0) "" } -array(6) { +array(7) { ["lifetime"]=> int(3600) ["path"]=> @@ -130,6 +145,24 @@ array(6) { string(3) "foo" ["secure"]=> bool(true) + ["partitioned"]=> + bool(false) + ["httponly"]=> + bool(true) + ["samesite"]=> + string(3) "foo" +} +array(7) { + ["lifetime"]=> + int(3600) + ["path"]=> + string(5) "/path" + ["domain"]=> + string(3) "foo" + ["secure"]=> + bool(true) + ["partitioned"]=> + bool(true) ["httponly"]=> bool(true) ["samesite"]=> diff --git a/ext/session/tests/session_regenerate_id_cookie.phpt b/ext/session/tests/session_regenerate_id_cookie.phpt index f1dc0727205..6516ad7061d 100644 --- a/ext/session/tests/session_regenerate_id_cookie.phpt +++ b/ext/session/tests/session_regenerate_id_cookie.phpt @@ -55,7 +55,7 @@ ob_end_flush(); ?>'); $extra_arguments = getenv('TEST_PHP_EXTRA_ARGS'); -var_dump(`$php $extra_arguments -d session.name=PHPSESSID $file`); +var_dump(shell_exec("$php $extra_arguments -d session.name=PHPSESSID $file")); unlink($file); diff --git a/ext/session/tests/session_start_partitioned.phpt b/ext/session/tests/session_start_partitioned.phpt new file mode 100644 index 00000000000..c2c1b33ae07 --- /dev/null +++ b/ext/session/tests/session_start_partitioned.phpt @@ -0,0 +1,31 @@ +--TEST-- +session_start() with partitioned cookies +--INI-- +session.use_strict_mode=0 +session.save_handler=files +session.save_path= +session.cookie_secure=0 +session.cookie_partitioned=0 +--EXTENSIONS-- +session +--SKIPIF-- + +--FILE-- + true])); +var_dump(session_start(['cookie_partitioned' => true, 'cookie_secure' => false])); +var_dump(session_start(['cookie_partitioned' => true, 'cookie_secure' => true])); + +ob_end_flush(); + +?> +--EXPECTF-- +Warning: session_start(): Partitioned session cookie cannot be used without also configuring it as secure in %s on line %d +bool(false) + +Warning: session_start(): Partitioned session cookie cannot be used without also configuring it as secure in %s on line %d +bool(false) +bool(true) diff --git a/ext/session/tests/session_start_partitioned_headers.phpt b/ext/session/tests/session_start_partitioned_headers.phpt new file mode 100644 index 00000000000..6fa3815aa85 --- /dev/null +++ b/ext/session/tests/session_start_partitioned_headers.phpt @@ -0,0 +1,13 @@ +--TEST-- +session_start() with partitioned cookies - header test +--EXTENSIONS-- +session +--FILE-- + true, "partitioned" => true]); +session_start(); +?> +--EXPECTHEADERS-- +Set-Cookie: PHPSESSID=12345; path=/; secure; Partitioned +--EXPECT-- diff --git a/ext/shmop/shmop_arginfo.h b/ext/shmop/shmop_arginfo.h index 8e763ac87f7..f376b8556d9 100644 --- a/ext/shmop/shmop_arginfo.h +++ b/ext/shmop/shmop_arginfo.h @@ -55,10 +55,8 @@ static void register_shmop_symbols(int module_number) zend_attribute *attribute_Deprecated_func_shmop_close_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "shmop_close", sizeof("shmop_close") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_func_shmop_close_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_func_shmop_close_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_shmop_close_0_arg1; zend_string *attribute_Deprecated_func_shmop_close_0_arg1_str = zend_string_init("as Shmop objects are freed automatically", strlen("as Shmop objects are freed automatically"), 1); - ZVAL_STR(&attribute_Deprecated_func_shmop_close_0_arg1, attribute_Deprecated_func_shmop_close_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_shmop_close_0->args[1].value, &attribute_Deprecated_func_shmop_close_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_shmop_close_0->args[1].value, attribute_Deprecated_func_shmop_close_0_arg1_str); attribute_Deprecated_func_shmop_close_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); } diff --git a/ext/simplexml/tests/033.phpt b/ext/simplexml/tests/033.phpt index 6fd52750ee0..6d681d7695c 100644 --- a/ext/simplexml/tests/033.phpt +++ b/ext/simplexml/tests/033.phpt @@ -25,8 +25,8 @@ var_dump((bool)$foo); var_dump((bool)$people); var_dump((int)$foo); var_dump((int)$people); -var_dump((double)$foo); -var_dump((double)$people); +var_dump((float)$foo); +var_dump((float)$people); var_dump((string)$foo); var_dump((string)$people); var_dump((array)$foo); diff --git a/ext/simplexml/tests/bug54973.phpt b/ext/simplexml/tests/bug54973.phpt index 5c9f6ffaca2..ad8a986ff56 100644 --- a/ext/simplexml/tests/bug54973.phpt +++ b/ext/simplexml/tests/bug54973.phpt @@ -11,8 +11,8 @@ var_dump($xml->number); $int = $xml->number / 1024 / 1024 / 1024; var_dump($int); -$double = (double) $xml->number / 1024 / 1024 / 1024; -var_dump($double); +$float = (float) $xml->number / 1024 / 1024 / 1024; +var_dump($float); ?> --EXPECT-- object(SimpleXMLElement)#2 (1) { diff --git a/ext/snmp/snmp.c b/ext/snmp/snmp.c index 915c4a46e1b..db2d0ad8786 100644 --- a/ext/snmp/snmp.c +++ b/ext/snmp/snmp.c @@ -1038,21 +1038,18 @@ static bool snmp_session_set_auth_protocol(struct snmp_session *s, zend_string * } #endif - smart_string err = {0}; - - smart_string_appends(&err, "Authentication protocol must be \"SHA\""); + zend_value_error( + "Authentication protocol must be \"SHA\"" #ifdef HAVE_SNMP_SHA256 - smart_string_appends(&err, " or \"SHA256\""); + " or \"SHA256\"" #endif #ifdef HAVE_SNMP_SHA512 - smart_string_appends(&err, " or \"SHA512\""); + " or \"SHA512\"" #endif #ifndef DISABLE_MD5 - smart_string_appends(&err, " or \"MD5\""); + " or \"MD5\"" #endif - smart_string_0(&err); - zend_value_error("%s", err.c); - smart_string_free(&err); + ); return false; } /* }}} */ diff --git a/ext/soap/php_encoding.c b/ext/soap/php_encoding.c index 8423f50fd4b..c37627e53a2 100644 --- a/ext/soap/php_encoding.c +++ b/ext/soap/php_encoding.c @@ -598,7 +598,7 @@ xmlNodePtr to_xml_user(encodeTypePtr type, zval *data, int style, xmlNodePtr par zval_ptr_dtor(&return_value); } if (!ret) { - ret = xmlNewNode(NULL, BAD_CAST("BOGUS")); + ret = xmlNewDocNode(parent->doc, NULL, BAD_CAST("BOGUS"), NULL); } xmlAddChild(parent, ret); if (style == SOAP_ENCODED) { @@ -855,7 +855,7 @@ static xmlNodePtr to_xml_string(encodeTypePtr type, zval *data, int style, xmlNo { xmlNodePtr ret, text; - ret = xmlNewNode(NULL, BAD_CAST("BOGUS")); + ret = xmlNewDocNode(parent->doc, NULL, BAD_CAST("BOGUS"), NULL); xmlAddChild(parent, ret); FIND_ZVAL_NULL(data, ret, style); @@ -937,7 +937,7 @@ static xmlNodePtr to_xml_base64(encodeTypePtr type, zval *data, int style, xmlNo { xmlNodePtr ret, text; - ret = xmlNewNode(NULL, BAD_CAST("BOGUS")); + ret = xmlNewDocNode(parent->doc, NULL, BAD_CAST("BOGUS"), NULL); xmlAddChild(parent, ret); FIND_ZVAL_NULL(data, ret, style); @@ -963,7 +963,7 @@ static xmlNodePtr to_xml_hexbin(encodeTypePtr type, zval *data, int style, xmlNo zval tmp; size_t i, j; - ret = xmlNewNode(NULL, BAD_CAST("BOGUS")); + ret = xmlNewDocNode(parent->doc, NULL, BAD_CAST("BOGUS"), NULL); xmlAddChild(parent, ret); FIND_ZVAL_NULL(data, ret, style); @@ -1066,7 +1066,7 @@ static xmlNodePtr to_xml_long(encodeTypePtr type, zval *data, int style, xmlNode { xmlNodePtr ret; - ret = xmlNewNode(NULL, BAD_CAST("BOGUS")); + ret = xmlNewDocNode(parent->doc, NULL, BAD_CAST("BOGUS"), NULL); xmlAddChild(parent, ret); FIND_ZVAL_NULL(data, ret, style); @@ -1093,7 +1093,7 @@ static xmlNodePtr to_xml_double(encodeTypePtr type, zval *data, int style, xmlNo zval tmp; char *str; - ret = xmlNewNode(NULL, BAD_CAST("BOGUS")); + ret = xmlNewDocNode(parent->doc, NULL, BAD_CAST("BOGUS"), NULL); xmlAddChild(parent, ret); FIND_ZVAL_NULL(data, ret, style); @@ -1141,7 +1141,7 @@ static xmlNodePtr to_xml_bool(encodeTypePtr type, zval *data, int style, xmlNode { xmlNodePtr ret; - ret = xmlNewNode(NULL, BAD_CAST("BOGUS")); + ret = xmlNewDocNode(parent->doc, NULL, BAD_CAST("BOGUS"), NULL); xmlAddChild(parent, ret); FIND_ZVAL_NULL(data, ret, style); @@ -1168,7 +1168,7 @@ static xmlNodePtr to_xml_null(encodeTypePtr type, zval *data, int style, xmlNode { xmlNodePtr ret; - ret = xmlNewNode(NULL, BAD_CAST("BOGUS")); + ret = xmlNewDocNode(parent->doc, NULL, BAD_CAST("BOGUS"), NULL); xmlAddChild(parent, ret); if (style == SOAP_ENCODED) { set_xsi_nil(ret); @@ -1306,12 +1306,12 @@ static void model_to_zval_object(zval *ret, sdlContentModelPtr model, xmlNodePtr } master_to_zval(&val, model->u.element->encode, r_node); } else if (model->u.element->fixed) { - xmlNodePtr dummy = xmlNewNode(NULL, BAD_CAST("BOGUS")); + xmlNodePtr dummy = xmlNewDocNode(node->doc, NULL, BAD_CAST("BOGUS"), NULL); xmlNodeSetContent(dummy, BAD_CAST(model->u.element->fixed)); master_to_zval(&val, model->u.element->encode, dummy); xmlFreeNode(dummy); } else if (model->u.element->def && !model->u.element->nillable) { - xmlNodePtr dummy = xmlNewNode(NULL, BAD_CAST("BOGUS")); + xmlNodePtr dummy = xmlNewDocNode(node->doc, NULL, BAD_CAST("BOGUS"), NULL); xmlNodeSetContent(dummy, BAD_CAST(model->u.element->def)); master_to_zval(&val, model->u.element->encode, dummy); xmlFreeNode(dummy); @@ -1331,12 +1331,12 @@ static void model_to_zval_object(zval *ret, sdlContentModelPtr model, xmlNodePtr } master_to_zval(&val, model->u.element->encode, node); } else if (model->u.element->fixed) { - xmlNodePtr dummy = xmlNewNode(NULL, BAD_CAST("BOGUS")); + xmlNodePtr dummy = xmlNewDocNode(node->doc, NULL, BAD_CAST("BOGUS"), NULL); xmlNodeSetContent(dummy, BAD_CAST(model->u.element->fixed)); master_to_zval(&val, model->u.element->encode, dummy); xmlFreeNode(dummy); } else if (model->u.element->def && !model->u.element->nillable) { - xmlNodePtr dummy = xmlNewNode(NULL, BAD_CAST("BOGUS")); + xmlNodePtr dummy = xmlNewDocNode(node->doc, NULL, BAD_CAST("BOGUS"), NULL); xmlNodeSetContent(dummy, BAD_CAST(model->u.element->def)); master_to_zval(&val, model->u.element->encode, dummy); xmlFreeNode(dummy); @@ -1541,7 +1541,7 @@ static zval *to_zval_object_ex(zval *ret, encodeTypePtr type, xmlNodePtr data, z xmlNodePtr dummy, text; zval data; - dummy = xmlNewNode(NULL, BAD_CAST("BOGUS")); + dummy = xmlNewDocNode(NULL, NULL, BAD_CAST("BOGUS"), NULL); text = xmlNewText(BAD_CAST(str_val)); xmlAddChild(dummy, text); ZVAL_NULL(&data); @@ -1646,7 +1646,7 @@ static int model_to_xml_object(xmlNodePtr node, sdlContentModelPtr model, zval * ZEND_HASH_FOREACH_VAL(ht, val) { ZVAL_DEREF(val); if (Z_TYPE_P(val) == IS_NULL && model->u.element->nillable) { - property = xmlNewNode(NULL, BAD_CAST("BOGUS")); + property = xmlNewDocNode(node->doc, NULL, BAD_CAST("BOGUS"), NULL); xmlAddChild(node, property); set_xsi_nil(property); } else { @@ -1666,7 +1666,7 @@ static int model_to_xml_object(xmlNodePtr node, sdlContentModelPtr model, zval * } ZEND_HASH_FOREACH_END(); } else { if (Z_TYPE_P(data) == IS_NULL && model->u.element->nillable) { - property = xmlNewNode(NULL, BAD_CAST("BOGUS")); + property = xmlNewDocNode(node->doc, NULL, BAD_CAST("BOGUS"), NULL); xmlAddChild(node, property); set_xsi_nil(property); } else if (Z_TYPE_P(data) == IS_NULL && model->min_occurs == 0) { @@ -1688,7 +1688,7 @@ static int model_to_xml_object(xmlNodePtr node, sdlContentModelPtr model, zval * } return 1; } else if (strict && model->u.element->nillable && model->min_occurs > 0) { - property = xmlNewNode(NULL, BAD_CAST(model->u.element->name)); + property = xmlNewDocNode(node->doc, NULL, BAD_CAST(model->u.element->name), NULL); xmlAddChild(node, property); set_xsi_nil(property); if (style == SOAP_LITERAL && @@ -1816,7 +1816,7 @@ static xmlNodePtr to_xml_object(encodeTypePtr type, zval *data, int style, xmlNo sdlTypePtr sdlType = type->sdl_type; if (!data || Z_TYPE_P(data) == IS_NULL) { - xmlParam = xmlNewNode(NULL, BAD_CAST("BOGUS")); + xmlParam = xmlNewDocNode(parent->doc, NULL, BAD_CAST("BOGUS"), NULL); xmlAddChild(parent, xmlParam); if (style == SOAP_ENCODED) { set_xsi_nil(xmlParam); @@ -1851,11 +1851,11 @@ static xmlNodePtr to_xml_object(encodeTypePtr type, zval *data, int style, xmlNo } else if (prop == NULL) { xmlParam = master_to_xml(enc, data, style, parent); } else { - xmlParam = xmlNewNode(NULL, BAD_CAST("BOGUS")); + xmlParam = xmlNewDocNode(parent->doc, NULL, BAD_CAST("BOGUS"), NULL); xmlAddChild(parent, xmlParam); } } else { - xmlParam = xmlNewNode(NULL, BAD_CAST("BOGUS")); + xmlParam = xmlNewDocNode(parent->doc, NULL, BAD_CAST("BOGUS"), NULL); xmlAddChild(parent, xmlParam); } } else if (sdlType->kind == XSD_TYPEKIND_EXTENSION && @@ -1877,12 +1877,12 @@ static xmlNodePtr to_xml_object(encodeTypePtr type, zval *data, int style, xmlNo } else if (prop == NULL) { xmlParam = master_to_xml(sdlType->encode, data, style, parent); } else { - xmlParam = xmlNewNode(NULL, BAD_CAST("BOGUS")); + xmlParam = xmlNewDocNode(parent->doc, NULL, BAD_CAST("BOGUS"), NULL); xmlAddChild(parent, xmlParam); } } } else { - xmlParam = xmlNewNode(NULL, BAD_CAST("BOGUS")); + xmlParam = xmlNewDocNode(parent->doc, NULL, BAD_CAST("BOGUS"), NULL); xmlAddChild(parent, xmlParam); } @@ -1903,7 +1903,7 @@ static xmlNodePtr to_xml_object(encodeTypePtr type, zval *data, int style, xmlNo xmlNodePtr property; ZVAL_DEREF(val); if (Z_TYPE_P(val) == IS_NULL && array_el->nillable) { - property = xmlNewNode(NULL, BAD_CAST("BOGUS")); + property = xmlNewDocNode(parent->doc, NULL, BAD_CAST("BOGUS"), NULL); xmlAddChild(xmlParam, property); set_xsi_nil(property); } else { @@ -1924,6 +1924,11 @@ static xmlNodePtr to_xml_object(encodeTypePtr type, zval *data, int style, xmlNo sdlAttributePtr attr; zval *zattr, rv; + /* Attributes can't refer to other attributes as there's nothing to attach the href to. */ + HashTable **ref_map = &SOAP_GLOBAL(ref_map); + HashTable *old_ref_map = *ref_map; + *ref_map = NULL; + ZEND_HASH_FOREACH_PTR(sdlType->attributes, attr) { if (attr->name) { zattr = get_zval_property(data, attr->name, &rv); @@ -1953,13 +1958,15 @@ static xmlNodePtr to_xml_object(encodeTypePtr type, zval *data, int style, xmlNo } } } ZEND_HASH_FOREACH_END(); + + *ref_map = old_ref_map; } } if (style == SOAP_ENCODED) { set_ns_and_type(xmlParam, type); } } else { - xmlParam = xmlNewNode(NULL, BAD_CAST("BOGUS")); + xmlParam = xmlNewDocNode(parent->doc, NULL, BAD_CAST("BOGUS"), NULL); xmlAddChild(parent, xmlParam); if (soap_check_zval_ref(data, xmlParam)) { @@ -2159,7 +2166,7 @@ static void add_xml_array_elements(xmlNodePtr xmlParam, if (dimension == 1) { while (j < dims[0]) { - xparam = xmlNewNode(NULL, BAD_CAST("BOGUS")); + xparam = xmlNewDocNode(xmlParam->doc, NULL, BAD_CAST("BOGUS"), NULL); xmlAddChild(xmlParam, xparam); if (type) { @@ -2186,7 +2193,7 @@ static void add_xml_array_elements(xmlNodePtr xmlParam, if (dimension == 1) { xmlNodePtr xparam; - xparam = xmlNewNode(NULL, BAD_CAST("BOGUS")); + xparam = xmlNewDocNode(xmlParam->doc, NULL, BAD_CAST("BOGUS"), NULL); xmlAddChild(xmlParam, xparam); if (type) { xmlNodeSetName(xparam, BAD_CAST(type->name)); @@ -2219,7 +2226,7 @@ static xmlNodePtr to_xml_array(encodeTypePtr type, zval *data, int style, xmlNod ZVAL_UNDEF(&array_copy); soap_version = SOAP_GLOBAL(soap_version); - xmlParam = xmlNewNode(NULL, BAD_CAST("BOGUS")); + xmlParam = xmlNewDocNode(parent->doc, NULL, BAD_CAST("BOGUS"), NULL); xmlAddChild(parent, xmlParam); if (!data || Z_TYPE_P(data) == IS_NULL) { @@ -2714,7 +2721,7 @@ static xmlNodePtr to_xml_map(encodeTypePtr type, zval *data, int style, xmlNodeP xmlNodePtr xparam, item; xmlNodePtr key; - xmlParam = xmlNewNode(NULL, BAD_CAST("BOGUS")); + xmlParam = xmlNewDocNode(parent->doc, NULL, BAD_CAST("BOGUS"), NULL); xmlAddChild(parent, xmlParam); FIND_ZVAL_NULL(data, xmlParam, style); @@ -2727,9 +2734,9 @@ static xmlNodePtr to_xml_map(encodeTypePtr type, zval *data, int style, xmlNodeP GC_TRY_PROTECT_RECURSION(Z_ARRVAL_P(data)); ZEND_HASH_FOREACH_KEY_VAL_IND(Z_ARRVAL_P(data), int_val, key_val, temp_data) { - item = xmlNewNode(NULL, BAD_CAST("item")); + item = xmlNewDocNode(parent->doc, NULL, BAD_CAST("item"), NULL); xmlAddChild(xmlParam, item); - key = xmlNewNode(NULL, BAD_CAST("key")); + key = xmlNewDocNode(parent->doc, NULL, BAD_CAST("key"), NULL); xmlAddChild(item,key); if (key_val) { if (style == SOAP_ENCODED) { @@ -2920,7 +2927,7 @@ static xmlNodePtr to_xml_datetime_ex(encodeTypePtr type, zval *data, char *forma xmlNodePtr xmlParam; - xmlParam = xmlNewNode(NULL, BAD_CAST("BOGUS")); + xmlParam = xmlNewDocNode(parent->doc, NULL, BAD_CAST("BOGUS"), NULL); xmlAddChild(parent, xmlParam); FIND_ZVAL_NULL(data, xmlParam, style); @@ -3052,9 +3059,15 @@ static xmlNodePtr to_xml_list(encodeTypePtr enc, zval *data, int style, xmlNodeP } ZEND_HASH_FOREACH_END(); } - ret = xmlNewNode(NULL, BAD_CAST("BOGUS")); + ret = xmlNewDocNode(parent->doc, NULL, BAD_CAST("BOGUS"), NULL); xmlAddChild(parent, ret); FIND_ZVAL_NULL(data, ret, style); + + /* Literals are unique and can't refer to other references via attributes. */ + HashTable **ref_map = &SOAP_GLOBAL(ref_map); + HashTable *old_ref_map = *ref_map; + *ref_map = NULL; + if (Z_TYPE_P(data) == IS_ARRAY) { zval *tmp; smart_str list = {0}; @@ -3129,6 +3142,7 @@ static xmlNodePtr to_xml_list(encodeTypePtr enc, zval *data, int style, xmlNodeP zval_ptr_dtor_str(&tmp); } } + *ref_map = old_ref_map; return ret; } diff --git a/ext/soap/soap.c b/ext/soap/soap.c index 0786ac81105..3d4edd3b7b7 100644 --- a/ext/soap/soap.c +++ b/ext/soap/soap.c @@ -453,7 +453,6 @@ static void php_soap_init_globals(zend_soap_globals *soap_globals) soap_globals->soap_version = SOAP_1_1; soap_globals->mem_cache = NULL; soap_globals->ref_map = NULL; - soap_globals->lang_en = zend_string_init_interned(ZEND_STRL("en"), true); } PHP_MSHUTDOWN_FUNCTION(soap) @@ -553,6 +552,8 @@ PHP_MINIT_FUNCTION(soap) old_error_handler = zend_error_cb; zend_error_cb = soap_error_handler; + SOAP_GLOBAL(lang_en) = zend_string_init_interned(ZEND_STRL("en"), true); + return SUCCESS; } @@ -3716,7 +3717,7 @@ static xmlDocPtr serialize_response_call(sdlFunctionPtr function, const char *fu if (version == SOAP_1_1) { tmp = Z_FAULT_CODE_P(ret); if (Z_TYPE_P(tmp) == IS_STRING) { - xmlNodePtr node = xmlNewNode(NULL, BAD_CAST("faultcode")); + xmlNodePtr node = xmlNewDocNode(doc, NULL, BAD_CAST("faultcode"), NULL); zend_string *str = php_escape_html_entities((unsigned char*)Z_STRVAL_P(tmp), Z_STRLEN_P(tmp), 0, 0, NULL); xmlAddChild(param, node); if (fault_ns) { @@ -3780,7 +3781,7 @@ static xmlDocPtr serialize_response_call(sdlFunctionPtr function, const char *fu if (Z_TYPE_P(tmp) > IS_NULL) { detail = tmp; } - node = xmlNewNode(NULL, BAD_CAST(detail_name)); + node = xmlNewDocNode(doc, NULL, BAD_CAST(detail_name), NULL); xmlAddChild(param, node); zend_hash_internal_pointer_reset(fault->details); @@ -4112,7 +4113,7 @@ static xmlDocPtr serialize_function_call(zval *this_ptr, sdlFunctionPtr function h = master_to_xml(enc, data, hdr_use, head); xmlNodeSetName(h, BAD_CAST(Z_STRVAL_P(name))); } else { - h = xmlNewNode(NULL, BAD_CAST(Z_STRVAL_P(name))); + h = xmlNewDocNode(doc, NULL, BAD_CAST(Z_STRVAL_P(name)), NULL); xmlAddChild(head, h); } nsptr = encode_add_ns(h, Z_STRVAL_P(ns)); @@ -4205,7 +4206,7 @@ static xmlNodePtr serialize_zval(zval *val, sdlParamPtr param, const char *param } xmlParam = master_to_xml(enc, val, style, parent); zval_ptr_dtor(&defval); - if (xmlParam != NULL) { + if (xmlParam != NULL) { if (xmlParam->name == NULL || strcmp((char*)xmlParam->name, "BOGUS") == 0) { xmlNodeSetName(xmlParam, BAD_CAST(paramName)); } diff --git a/ext/soap/soap_arginfo.h b/ext/soap/soap_arginfo.h index f69659b4b0f..a8577cb5cf3 100644 --- a/ext/soap/soap_arginfo.h +++ b/ext/soap/soap_arginfo.h @@ -320,10 +320,8 @@ static void register_soap_symbols(int module_number) zend_attribute *attribute_Deprecated_const_SOAP_FUNCTIONS_ALL_0 = zend_add_global_constant_attribute(const_SOAP_FUNCTIONS_ALL, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_const_SOAP_FUNCTIONS_ALL_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_4)); attribute_Deprecated_const_SOAP_FUNCTIONS_ALL_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_const_SOAP_FUNCTIONS_ALL_0_arg1; zend_string *attribute_Deprecated_const_SOAP_FUNCTIONS_ALL_0_arg1_str = zend_string_init("as enabling all functions is a possible security concern", strlen("as enabling all functions is a possible security concern"), 1); - ZVAL_STR(&attribute_Deprecated_const_SOAP_FUNCTIONS_ALL_0_arg1, attribute_Deprecated_const_SOAP_FUNCTIONS_ALL_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_const_SOAP_FUNCTIONS_ALL_0->args[1].value, &attribute_Deprecated_const_SOAP_FUNCTIONS_ALL_0_arg1); + ZVAL_STR(&attribute_Deprecated_const_SOAP_FUNCTIONS_ALL_0->args[1].value, attribute_Deprecated_const_SOAP_FUNCTIONS_ALL_0_arg1_str); attribute_Deprecated_const_SOAP_FUNCTIONS_ALL_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); } diff --git a/ext/soap/tests/bugs/gh18640.phpt b/ext/soap/tests/bugs/gh18640.phpt new file mode 100644 index 00000000000..493659eca30 --- /dev/null +++ b/ext/soap/tests/bugs/gh18640.phpt @@ -0,0 +1,42 @@ +--TEST--- +GH-18640 (heap-use-after-free ext/soap/php_encoding.c:299:32 in soap_check_zval_ref) +--EXTENSIONS-- +soap +--CREDITS-- +YuanchengJiang +--FILE-- + 1, 'classmap' => ['logOnEvent' => 'LogOnEvent', 'events' => 'IVREvents']]); +$timestamp = new LogOnEvent(); // Bogus! +$logOffEvents[] = new LogOffEvent($timestamp); +$logOffEvents[] = new LogOffEvent($timestamp); +$ivrEvents = new IVREvents($logOffEvents); +$result = $soapClient->PostEvents($ivrEvents); + +class LogOffEvent { + function __construct(public $timestamp) { + $this->timestamp = $timestamp; + } +} + +class LogOnEvent { +} + +class IVREvents { + function __construct(public $logOffEvent) { + } +} +?> +--EXPECT-- +string(359) " + +" diff --git a/ext/sockets/config.m4 b/ext/sockets/config.m4 index f637c32b3b6..bf183f5e6e7 100644 --- a/ext/sockets/config.m4 +++ b/ext/sockets/config.m4 @@ -4,7 +4,7 @@ PHP_ARG_ENABLE([sockets], [Enable sockets support])]) if test "$PHP_SOCKETS" != "no"; then - AC_CHECK_FUNCS([hstrerror if_nametoindex if_indextoname sockatmark]) + AC_CHECK_FUNCS([hstrerror if_nametoindex if_indextoname sockatmark accept4]) AC_CHECK_HEADERS([sys/sockio.h linux/filter.h linux/if_packet.h linux/if_ether.h linux/udp.h]) AC_DEFINE([HAVE_SOCKETS], [1], [Define to 1 if the PHP extension 'sockets' is available.]) diff --git a/ext/sockets/conversions.c b/ext/sockets/conversions.c index b1a4c3486d7..e5894a1de83 100644 --- a/ext/sockets/conversions.c +++ b/ext/sockets/conversions.c @@ -930,7 +930,7 @@ static void from_zval_write_control_array(const zval *arr, char *msghdr_c, ser_c char *bufp = buf; zval *elem; uint32_t i = 0; - int num_elems; + uint32_t num_elems; void *control_buf; zend_llist_element *alloc; size_t control_len, @@ -1102,7 +1102,7 @@ static void from_zval_write_iov_array_aux(zval *elem, unsigned i, void **args, s } static void from_zval_write_iov_array(const zval *arr, char *msghdr_c, ser_context *ctx) { - int num_elem; + uint32_t num_elem; struct msghdr *msg = (struct msghdr*)msghdr_c; if (Z_TYPE_P(arr) != IS_ARRAY) { @@ -1361,7 +1361,7 @@ void to_zval_read_ucred(const char *data, zval *zv, res_context *ctx) #ifdef SCM_RIGHTS size_t calculate_scm_rights_space(const zval *arr, ser_context *ctx) { - int num_elems; + uint32_t num_elems; if (Z_TYPE_P(arr) != IS_ARRAY) { do_from_zval_err(ctx, "%s", "expected an array here"); @@ -1374,7 +1374,7 @@ size_t calculate_scm_rights_space(const zval *arr, ser_context *ctx) return (size_t)-1; } - return zend_hash_num_elements(Z_ARRVAL_P(arr)) * sizeof(int); + return num_elems * sizeof(int); } static void from_zval_write_fd_array_aux(zval *elem, unsigned i, void **args, ser_context *ctx) { @@ -1420,7 +1420,7 @@ void from_zval_write_fd_array(const zval *arr, char *int_arr, ser_context *ctx) void to_zval_read_fd_array(const char *data, zval *zv, res_context *ctx) { size_t *cmsg_len; - int num_elems, + uint32_t num_elems, i; struct cmsghdr *dummy_cmsg = 0; size_t data_offset; diff --git a/ext/sockets/sockaddr_conv.c b/ext/sockets/sockaddr_conv.c index 9840a98dbcb..333ef2533a1 100644 --- a/ext/sockets/sockaddr_conv.c +++ b/ext/sockets/sockaddr_conv.c @@ -137,8 +137,7 @@ int php_set_inet46_addr(php_sockaddr_storage *ss, socklen_t *ss_len, zend_string } #endif else { - php_error_docref(NULL, E_WARNING, - "IP address used in the context of an unexpected type of socket"); + zend_value_error("IP address used in the context of an unexpected type of socket"); } return 0; } diff --git a/ext/sockets/sockets.c b/ext/sockets/sockets.c index 2f2eb3465fd..3cae726838a 100644 --- a/ext/sockets/sockets.c +++ b/ext/sockets/sockets.c @@ -283,6 +283,19 @@ static bool php_open_listen_sock(php_socket *sock, unsigned short port, int back static bool php_accept_connect(php_socket *in_sock, php_socket *out_sock, struct sockaddr *la, socklen_t *la_len) /* {{{ */ { +#if defined(HAVE_ACCEPT4) + int flags = SOCK_CLOEXEC; + if (!in_sock->blocking) { + flags |= SOCK_NONBLOCK; + } + + out_sock->bsd_socket = accept4(in_sock->bsd_socket, la, la_len, flags); + + if (IS_INVALID_SOCKET(out_sock)) { + PHP_SOCKET_ERROR(out_sock, "unable to accept incoming connection", errno); + return 0; + } +#else out_sock->bsd_socket = accept(in_sock->bsd_socket, la, la_len); if (IS_INVALID_SOCKET(out_sock)) { @@ -292,7 +305,7 @@ static bool php_accept_connect(php_socket *in_sock, php_socket *out_sock, struct #if !defined(PHP_WIN32) /** - * accept4 could had been used but not all platforms support it (e.g. Haiku, solaris < 11.4, ...) + * for fewer and fewer platforms not supporting accept4 syscall we use fcntl instead, * win32, not having any concept of child process, has no need to address it. */ int mode; @@ -310,6 +323,7 @@ static bool php_accept_connect(php_socket *in_sock, php_socket *out_sock, struct return 0; } } +#endif #endif out_sock->error = 0; @@ -2571,7 +2585,7 @@ PHP_FUNCTION(socket_import_stream) ZEND_PARSE_PARAMETERS_END(); php_stream_from_zval(stream, zstream); - if (php_stream_cast(stream, PHP_STREAM_AS_SOCKETD, (void**)&socket, 1)) { + if (php_stream_cast(stream, PHP_STREAM_AS_SOCKETD, (void**)&socket, 1) == FAILURE) { /* error supposedly already shown */ RETURN_FALSE; } diff --git a/ext/sockets/tests/mcast_sockettype_error.phpt b/ext/sockets/tests/mcast_sockettype_error.phpt new file mode 100644 index 00000000000..56308534ebc --- /dev/null +++ b/ext/sockets/tests/mcast_sockettype_error.phpt @@ -0,0 +1,30 @@ +--TEST-- +Multicast attempt on unsupported socket type +--EXTENSIONS-- +sockets +--SKIPIF-- + +--FILE-- + '127.0.0.1', + "interface" => "lo", + )); +} catch (\ValueError $e) { + echo $e->getMessage(), PHP_EOL; +} +?> +--EXPECT-- +IP address used in the context of an unexpected type of socket diff --git a/ext/sockets/tests/socket_export_stream-5.phpt b/ext/sockets/tests/socket_export_stream-5.phpt deleted file mode 100644 index ffad1935b64..00000000000 --- a/ext/sockets/tests/socket_export_stream-5.phpt +++ /dev/null @@ -1,24 +0,0 @@ ---TEST-- -socket_export_stream: effects of leaked handles ---EXTENSIONS-- -sockets -zend_test ---INI-- -report_memleaks=0 ---FILE-- - ---EXPECT-- -Done. diff --git a/ext/sockets/tests/socket_import_stream-5.phpt b/ext/sockets/tests/socket_import_stream-5.phpt deleted file mode 100644 index 9a684d054ba..00000000000 --- a/ext/sockets/tests/socket_import_stream-5.phpt +++ /dev/null @@ -1,22 +0,0 @@ ---TEST-- -socket_import_stream: effects of leaked handles ---EXTENSIONS-- -sockets -zend_test ---INI-- -report_memleaks=0 ---FILE-- - ---EXPECT-- -Done. diff --git a/ext/sodium/config.m4 b/ext/sodium/config.m4 index 40da5e5bf2d..178568d72ae 100644 --- a/ext/sodium/config.m4 +++ b/ext/sodium/config.m4 @@ -19,8 +19,7 @@ if test "$PHP_SODIUM" != "no"; then AS_IF([test "$ac_cv_sizeof_long" -eq 4], [ SODIUM_COMPILER_FLAGS="$SODIUM_COMPILER_FLAGS -Wno-type-limits" AX_CHECK_COMPILE_FLAG([-Wno-logical-op], - [SODIUM_COMPILER_FLAGS="$SODIUM_COMPILER_FLAGS -Wno-logical-op"],, - [-Werror]) + [SODIUM_COMPILER_FLAGS="$SODIUM_COMPILER_FLAGS -Wno-logical-op"]) ]) PHP_NEW_EXTENSION([sodium], diff --git a/ext/spl/php_spl.c b/ext/spl/php_spl.c index e6134c94b72..f796b936dae 100644 --- a/ext/spl/php_spl.c +++ b/ext/spl/php_spl.c @@ -582,6 +582,13 @@ PHP_FUNCTION(spl_autoload_unregister) if (fcc.function_handler && zend_string_equals_literal( fcc.function_handler->common.function_name, "spl_autoload_call")) { + php_error_docref(NULL, E_DEPRECATED, + "Using spl_autoload_call() as a callback for spl_autoload_unregister() is deprecated," + " to remove all registered autoloaders, call spl_autoload_unregister()" + " for all values returned from spl_autoload_functions()"); + if (UNEXPECTED(EG(exception))) { + RETURN_THROWS(); + } if (spl_autoload_functions) { /* Don't destroy the hash table, as we might be iterating over it right now. */ zend_hash_clean(spl_autoload_functions); diff --git a/ext/spl/spl_array.c b/ext/spl/spl_array.c index 5cb3e27bbb8..781872cda11 100644 --- a/ext/spl/spl_array.c +++ b/ext/spl/spl_array.c @@ -984,6 +984,12 @@ static void spl_array_set_array(zval *object, spl_array_object *intern, zval *ar } } } else { + php_error_docref(NULL, E_DEPRECATED, + "Using an object as a backing array for %s is deprecated, as it allows violating class constraints and invariants", + instanceof_function(Z_OBJCE_P(object), spl_ce_ArrayIterator) ? "ArrayIterator" : "ArrayObject"); + if (UNEXPECTED(EG(exception))) { + return; + } if (Z_OBJ_HT_P(array) == &spl_handler_ArrayObject) { ZVAL_COPY_VALUE(&garbage, &intern->array); if (just_array) { diff --git a/ext/spl/spl_directory.c b/ext/spl/spl_directory.c index 8c59e9624a3..049d850d12f 100644 --- a/ext/spl/spl_directory.c +++ b/ext/spl/spl_directory.c @@ -260,19 +260,16 @@ static zend_result spl_filesystem_object_get_file_name(spl_filesystem_object *in return SUCCESS; } /* }}} */ -/* TODO Make void or have callers check return value */ -static bool spl_filesystem_dir_read(spl_filesystem_object *intern) /* {{{ */ +static void spl_filesystem_dir_read(spl_filesystem_object *intern) /* {{{ */ { if (intern->file_name) { /* invalidate */ zend_string_release(intern->file_name); intern->file_name = NULL; } + if (!intern->u.dir.dirp || !php_stream_readdir(intern->u.dir.dirp, &intern->u.dir.entry)) { intern->u.dir.entry.d_name[0] = '\0'; - return 0; - } else { - return 1; } } /* }}} */ diff --git a/ext/spl/spl_fixedarray_arginfo.h b/ext/spl/spl_fixedarray_arginfo.h index 333ef5c3a69..d3d84deabe6 100644 --- a/ext/spl/spl_fixedarray_arginfo.h +++ b/ext/spl/spl_fixedarray_arginfo.h @@ -100,10 +100,8 @@ static zend_class_entry *register_class_SplFixedArray(zend_class_entry *class_en zend_attribute *attribute_Deprecated_func___wakeup_0 = zend_add_function_attribute(zend_hash_str_find_ptr(&class_entry->function_table, "__wakeup", sizeof("__wakeup") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_func___wakeup_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_4)); attribute_Deprecated_func___wakeup_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func___wakeup_0_arg1; zend_string *attribute_Deprecated_func___wakeup_0_arg1_str = zend_string_init("this method is obsolete, as serialization hooks are provided by __unserialize() and __serialize()", strlen("this method is obsolete, as serialization hooks are provided by __unserialize() and __serialize()"), 1); - ZVAL_STR(&attribute_Deprecated_func___wakeup_0_arg1, attribute_Deprecated_func___wakeup_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func___wakeup_0->args[1].value, &attribute_Deprecated_func___wakeup_0_arg1); + ZVAL_STR(&attribute_Deprecated_func___wakeup_0->args[1].value, attribute_Deprecated_func___wakeup_0_arg1_str); attribute_Deprecated_func___wakeup_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); return class_entry; diff --git a/ext/spl/spl_heap.c b/ext/spl/spl_heap.c index d4450da4200..628e24ac247 100644 --- a/ext/spl/spl_heap.c +++ b/ext/spl/spl_heap.c @@ -50,7 +50,7 @@ typedef struct _spl_ptr_heap { spl_ptr_heap_ctor_func ctor; spl_ptr_heap_dtor_func dtor; spl_ptr_heap_cmp_func cmp; - int count; + size_t count; int flags; size_t max_size; size_t elem_size; @@ -267,8 +267,6 @@ static spl_ptr_heap *spl_ptr_heap_init(spl_ptr_heap_cmp_func cmp, spl_ptr_heap_c /* }}} */ static void spl_ptr_heap_insert(spl_ptr_heap *heap, void *elem, void *cmp_userdata) { /* {{{ */ - int i; - if (heap->count+1 > heap->max_size) { size_t alloc_size = heap->max_size * heap->elem_size; /* we need to allocate more memory */ @@ -280,8 +278,9 @@ static void spl_ptr_heap_insert(spl_ptr_heap *heap, void *elem, void *cmp_userda heap->flags |= SPL_HEAP_WRITE_LOCKED; /* sifting up */ - for (i = heap->count; i > 0 && heap->cmp(spl_heap_elem(heap, (i-1)/2), elem, cmp_userdata) < 0; i = (i-1)/2) { - spl_heap_elem_copy(heap, spl_heap_elem(heap, i), spl_heap_elem(heap, (i-1)/2)); + size_t pos; + for (pos = heap->count; pos > 0 && heap->cmp(spl_heap_elem(heap, (pos-1)/2), elem, cmp_userdata) < 0; pos = (pos-1)/2) { + spl_heap_elem_copy(heap, spl_heap_elem(heap, pos), spl_heap_elem(heap, (pos-1)/2)); } heap->count++; @@ -292,7 +291,7 @@ static void spl_ptr_heap_insert(spl_ptr_heap *heap, void *elem, void *cmp_userda heap->flags |= SPL_HEAP_CORRUPTED; } - spl_heap_elem_copy(heap, spl_heap_elem(heap, i), elem); + spl_heap_elem_copy(heap, spl_heap_elem(heap, pos), elem); } /* }}} */ @@ -306,8 +305,7 @@ static void *spl_ptr_heap_top(spl_ptr_heap *heap) { /* {{{ */ /* }}} */ static zend_result spl_ptr_heap_delete_top(spl_ptr_heap *heap, void *elem, void *cmp_userdata) { /* {{{ */ - int i, j; - const int limit = (heap->count-1)/2; + const size_t limit = (heap->count-1)/2; void *bottom; if (heap->count == 0) { @@ -324,16 +322,17 @@ static zend_result spl_ptr_heap_delete_top(spl_ptr_heap *heap, void *elem, void bottom = spl_heap_elem(heap, --heap->count); - for (i = 0; i < limit; i = j) { + size_t parent_idx, child_idx; + for (parent_idx = 0; parent_idx < limit; parent_idx = child_idx) { /* Find smaller child */ - j = i * 2 + 1; - if (j != heap->count && heap->cmp(spl_heap_elem(heap, j+1), spl_heap_elem(heap, j), cmp_userdata) > 0) { - j++; /* next child is bigger */ + child_idx = parent_idx * 2 + 1; + if (child_idx != heap->count && heap->cmp(spl_heap_elem(heap, child_idx+1), spl_heap_elem(heap, child_idx), cmp_userdata) > 0) { + child_idx++; /* next child is bigger */ } /* swap elements between two levels */ - if(heap->cmp(bottom, spl_heap_elem(heap, j), cmp_userdata) < 0) { - spl_heap_elem_copy(heap, spl_heap_elem(heap, i), spl_heap_elem(heap, j)); + if(heap->cmp(bottom, spl_heap_elem(heap, child_idx), cmp_userdata) < 0) { + spl_heap_elem_copy(heap, spl_heap_elem(heap, parent_idx), spl_heap_elem(heap, child_idx)); } else { break; } @@ -346,7 +345,7 @@ static zend_result spl_ptr_heap_delete_top(spl_ptr_heap *heap, void *elem, void heap->flags |= SPL_HEAP_CORRUPTED; } - void *to = spl_heap_elem(heap, i); + void *to = spl_heap_elem(heap, parent_idx); if (to != bottom) { spl_heap_elem_copy(heap, to, bottom); } @@ -355,8 +354,6 @@ static zend_result spl_ptr_heap_delete_top(spl_ptr_heap *heap, void *elem, void /* }}} */ static spl_ptr_heap *spl_ptr_heap_clone(spl_ptr_heap *from) { /* {{{ */ - int i; - spl_ptr_heap *heap = emalloc(sizeof(spl_ptr_heap)); heap->dtor = from->dtor; @@ -370,7 +367,7 @@ static spl_ptr_heap *spl_ptr_heap_clone(spl_ptr_heap *from) { /* {{{ */ heap->elements = safe_emalloc(from->elem_size, from->max_size, 0); memcpy(heap->elements, from->elements, from->elem_size * from->max_size); - for (i = 0; i < heap->count; ++i) { + for (size_t i = 0; i < heap->count; ++i) { heap->ctor(spl_heap_elem(heap, i)); } @@ -384,11 +381,9 @@ static void spl_ptr_heap_destroy(spl_ptr_heap *heap) { /* {{{ */ return; } - int i; - heap->flags |= SPL_HEAP_WRITE_LOCKED; - for (i = 0; i < heap->count; ++i) { + for (size_t i = 0; i < heap->count; ++i) { heap->dtor(spl_heap_elem(heap, i)); } @@ -399,7 +394,7 @@ static void spl_ptr_heap_destroy(spl_ptr_heap *heap) { /* {{{ */ } /* }}} */ -static int spl_ptr_heap_count(spl_ptr_heap *heap) { /* {{{ */ +static size_t spl_ptr_heap_count(spl_ptr_heap *heap) { /* {{{ */ return heap->count; } /* }}} */ @@ -534,7 +529,7 @@ static HashTable* spl_heap_object_get_debug_info(const zend_class_entry *ce, zen array_init(&heap_array); - for (zend_ulong i = 0; i < intern->heap->count; ++i) { + for (size_t i = 0; i < intern->heap->count; ++i) { if (ce == spl_ce_SplPriorityQueue) { spl_pqueue_elem *pq_elem = spl_heap_elem(intern->heap, i); zval elem; diff --git a/ext/spl/spl_observer.c b/ext/spl/spl_observer.c index 4eeb3371027..540e5c2c0ff 100644 --- a/ext/spl/spl_observer.c +++ b/ext/spl/spl_observer.c @@ -25,6 +25,7 @@ #include "zend_smart_str.h" #include "zend_interfaces.h" #include "zend_exceptions.h" +#include "zend_attributes.h" #include "php_spl.h" /* For php_spl_object_hash() */ #include "spl_observer.h" diff --git a/ext/spl/spl_observer.stub.php b/ext/spl/spl_observer.stub.php index 9e78272cf35..1a3c1f68433 100644 --- a/ext/spl/spl_observer.stub.php +++ b/ext/spl/spl_observer.stub.php @@ -23,12 +23,15 @@ interface SplSubject class SplObjectStorage implements Countable, SeekableIterator, Serializable, ArrayAccess { /** @tentative-return-type */ + #[\Deprecated(since: '8.5', message: "use method SplObjectStorage::offsetSet() instead")] public function attach(object $object, mixed $info = null): void {} /** @tentative-return-type */ + #[\Deprecated(since: '8.5', message: "use method SplObjectStorage::offsetUnset() instead")] public function detach(object $object): void {} /** @tentative-return-type */ + #[\Deprecated(since: '8.5', message: "use method SplObjectStorage::offsetExists() instead")] public function contains(object $object): bool {} /** @tentative-return-type */ diff --git a/ext/spl/spl_observer_arginfo.h b/ext/spl/spl_observer_arginfo.h index be12c594e01..ae648edd7e8 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: a846c9dd240b6f0666cd5e805abfacabe360cf4c */ + * Stub hash: 9dfd8bcf8946cbee550c9a46da07c424c3505408 */ 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) @@ -185,9 +185,9 @@ static const zend_function_entry class_SplSubject_methods[] = { }; static const zend_function_entry class_SplObjectStorage_methods[] = { - ZEND_ME(SplObjectStorage, attach, arginfo_class_SplObjectStorage_attach, ZEND_ACC_PUBLIC) - ZEND_ME(SplObjectStorage, detach, arginfo_class_SplObjectStorage_detach, ZEND_ACC_PUBLIC) - ZEND_ME(SplObjectStorage, contains, arginfo_class_SplObjectStorage_contains, ZEND_ACC_PUBLIC) + ZEND_ME(SplObjectStorage, attach, arginfo_class_SplObjectStorage_attach, ZEND_ACC_PUBLIC|ZEND_ACC_DEPRECATED) + ZEND_ME(SplObjectStorage, detach, arginfo_class_SplObjectStorage_detach, ZEND_ACC_PUBLIC|ZEND_ACC_DEPRECATED) + ZEND_ME(SplObjectStorage, contains, arginfo_class_SplObjectStorage_contains, ZEND_ACC_PUBLIC|ZEND_ACC_DEPRECATED) ZEND_ME(SplObjectStorage, addAll, arginfo_class_SplObjectStorage_addAll, ZEND_ACC_PUBLIC) ZEND_ME(SplObjectStorage, removeAll, arginfo_class_SplObjectStorage_removeAll, ZEND_ACC_PUBLIC) ZEND_ME(SplObjectStorage, removeAllExcept, arginfo_class_SplObjectStorage_removeAllExcept, ZEND_ACC_PUBLIC) @@ -258,6 +258,28 @@ static zend_class_entry *register_class_SplObjectStorage(zend_class_entry *class class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zend_class_implements(class_entry, 4, class_entry_Countable, class_entry_SeekableIterator, class_entry_Serializable, class_entry_ArrayAccess); + + zend_attribute *attribute_Deprecated_func_attach_0 = zend_add_function_attribute(zend_hash_str_find_ptr(&class_entry->function_table, "attach", sizeof("attach") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + ZVAL_STR(&attribute_Deprecated_func_attach_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_5)); + attribute_Deprecated_func_attach_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zend_string *attribute_Deprecated_func_attach_0_arg1_str = zend_string_init("use method SplObjectStorage::offsetSet() instead", strlen("use method SplObjectStorage::offsetSet() instead"), 1); + ZVAL_STR(&attribute_Deprecated_func_attach_0->args[1].value, attribute_Deprecated_func_attach_0_arg1_str); + attribute_Deprecated_func_attach_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + + zend_attribute *attribute_Deprecated_func_detach_0 = zend_add_function_attribute(zend_hash_str_find_ptr(&class_entry->function_table, "detach", sizeof("detach") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + ZVAL_STR(&attribute_Deprecated_func_detach_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_5)); + attribute_Deprecated_func_detach_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zend_string *attribute_Deprecated_func_detach_0_arg1_str = zend_string_init("use method SplObjectStorage::offsetUnset() instead", strlen("use method SplObjectStorage::offsetUnset() instead"), 1); + ZVAL_STR(&attribute_Deprecated_func_detach_0->args[1].value, attribute_Deprecated_func_detach_0_arg1_str); + attribute_Deprecated_func_detach_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + + zend_attribute *attribute_Deprecated_func_contains_0 = zend_add_function_attribute(zend_hash_str_find_ptr(&class_entry->function_table, "contains", sizeof("contains") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + ZVAL_STR(&attribute_Deprecated_func_contains_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_5)); + attribute_Deprecated_func_contains_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zend_string *attribute_Deprecated_func_contains_0_arg1_str = zend_string_init("use method SplObjectStorage::offsetExists() instead", strlen("use method SplObjectStorage::offsetExists() instead"), 1); + ZVAL_STR(&attribute_Deprecated_func_contains_0->args[1].value, attribute_Deprecated_func_contains_0_arg1_str); + attribute_Deprecated_func_contains_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + return class_entry; } diff --git a/ext/spl/tests/ArrayObject__serialize_saves_iterator_class.phpt b/ext/spl/tests/ArrayObject/ArrayObject__serialize_saves_iterator_class.phpt similarity index 100% rename from ext/spl/tests/ArrayObject__serialize_saves_iterator_class.phpt rename to ext/spl/tests/ArrayObject/ArrayObject__serialize_saves_iterator_class.phpt diff --git a/ext/spl/tests/ArrayObject_clone_other_std_props.phpt b/ext/spl/tests/ArrayObject/ArrayObject_clone_other_std_props.phpt similarity index 64% rename from ext/spl/tests/ArrayObject_clone_other_std_props.phpt rename to ext/spl/tests/ArrayObject/ArrayObject_clone_other_std_props.phpt index 688954c3d7b..f527f5b6645 100644 --- a/ext/spl/tests/ArrayObject_clone_other_std_props.phpt +++ b/ext/spl/tests/ArrayObject/ArrayObject_clone_other_std_props.phpt @@ -9,7 +9,8 @@ $c = clone $b; var_dump($c); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d object(ArrayObject)#3 (1) { ["storage":"ArrayObject":private]=> array(3) { diff --git a/ext/spl/tests/ArrayObject_dump_during_sort.phpt b/ext/spl/tests/ArrayObject/ArrayObject_dump_during_sort.phpt similarity index 100% rename from ext/spl/tests/ArrayObject_dump_during_sort.phpt rename to ext/spl/tests/ArrayObject/ArrayObject_dump_during_sort.phpt diff --git a/ext/spl/tests/ArrayObject_enum.phpt b/ext/spl/tests/ArrayObject/ArrayObject_enum.phpt similarity index 57% rename from ext/spl/tests/ArrayObject_enum.phpt rename to ext/spl/tests/ArrayObject/ArrayObject_enum.phpt index 906c89b54df..a88da8fc553 100644 --- a/ext/spl/tests/ArrayObject_enum.phpt +++ b/ext/spl/tests/ArrayObject/ArrayObject_enum.phpt @@ -11,5 +11,7 @@ new ArrayObject(Foo::Bar); ?> --EXPECTF-- +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d + Fatal error: Uncaught InvalidArgumentException: Enums are not compatible with ArrayObject in %s:%d %a diff --git a/ext/spl/tests/ArrayObject_exchange_array_during_sorting.phpt b/ext/spl/tests/ArrayObject/ArrayObject_exchange_array_during_sorting.phpt similarity index 100% rename from ext/spl/tests/ArrayObject_exchange_array_during_sorting.phpt rename to ext/spl/tests/ArrayObject/ArrayObject_exchange_array_during_sorting.phpt diff --git a/ext/spl/tests/ArrayObject_get_object_vars.phpt b/ext/spl/tests/ArrayObject/ArrayObject_get_object_vars.phpt similarity index 69% rename from ext/spl/tests/ArrayObject_get_object_vars.phpt rename to ext/spl/tests/ArrayObject/ArrayObject_get_object_vars.phpt index a80add6b95a..2e6b3d27f15 100644 --- a/ext/spl/tests/ArrayObject_get_object_vars.phpt +++ b/ext/spl/tests/ArrayObject/ArrayObject_get_object_vars.phpt @@ -21,7 +21,8 @@ var_dump(get_object_vars($ao)); var_dump($ao->getObjectVars()); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d array(0) { } array(1) { diff --git a/ext/spl/tests/ArrayObject_illegal_offset.phpt b/ext/spl/tests/ArrayObject/ArrayObject_illegal_offset.phpt similarity index 100% rename from ext/spl/tests/ArrayObject_illegal_offset.phpt rename to ext/spl/tests/ArrayObject/ArrayObject_illegal_offset.phpt diff --git a/ext/spl/tests/ArrayObject_modify_shared_object_properties.phpt b/ext/spl/tests/ArrayObject/ArrayObject_modify_shared_object_properties.phpt similarity index 58% rename from ext/spl/tests/ArrayObject_modify_shared_object_properties.phpt rename to ext/spl/tests/ArrayObject/ArrayObject_modify_shared_object_properties.phpt index 24c247cabd9..69424204456 100644 --- a/ext/spl/tests/ArrayObject_modify_shared_object_properties.phpt +++ b/ext/spl/tests/ArrayObject/ArrayObject_modify_shared_object_properties.phpt @@ -10,7 +10,8 @@ $ao['a'] = 42; var_dump($arr); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d array(2) { ["a"]=> int(1) diff --git a/ext/spl/tests/ArrayObject_overloaded_SplFixedArray.phpt b/ext/spl/tests/ArrayObject/ArrayObject_overloaded_SplFixedArray.phpt similarity index 69% rename from ext/spl/tests/ArrayObject_overloaded_SplFixedArray.phpt rename to ext/spl/tests/ArrayObject/ArrayObject_overloaded_SplFixedArray.phpt index f46e4cc1c9a..13065b4ac38 100644 --- a/ext/spl/tests/ArrayObject_overloaded_SplFixedArray.phpt +++ b/ext/spl/tests/ArrayObject/ArrayObject_overloaded_SplFixedArray.phpt @@ -12,5 +12,6 @@ try { echo $e->getMessage(), "\n"; } ?> ---EXPECT-- +--EXPECTF-- +Deprecated: ArrayObject::exchangeArray(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d Overloaded object of type SplFixedArray is not compatible with ArrayObject diff --git a/ext/spl/tests/ArrayObject_overloaded_object_incompatible.phpt b/ext/spl/tests/ArrayObject/ArrayObject_overloaded_object_incompatible.phpt similarity index 71% rename from ext/spl/tests/ArrayObject_overloaded_object_incompatible.phpt rename to ext/spl/tests/ArrayObject/ArrayObject_overloaded_object_incompatible.phpt index 67267f0ec6a..8cc66facc00 100644 --- a/ext/spl/tests/ArrayObject_overloaded_object_incompatible.phpt +++ b/ext/spl/tests/ArrayObject/ArrayObject_overloaded_object_incompatible.phpt @@ -12,7 +12,8 @@ try { var_dump($ao); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: ArrayObject::exchangeArray(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d Overloaded object of type DateInterval is not compatible with ArrayObject object(ArrayObject)#1 (1) { ["storage":"ArrayObject":private]=> diff --git a/ext/spl/tests/ArrayObject_proptable_canonicalization.phpt b/ext/spl/tests/ArrayObject/ArrayObject_proptable_canonicalization.phpt similarity index 57% rename from ext/spl/tests/ArrayObject_proptable_canonicalization.phpt rename to ext/spl/tests/ArrayObject/ArrayObject_proptable_canonicalization.phpt index 006a1526026..fd10797f72b 100644 --- a/ext/spl/tests/ArrayObject_proptable_canonicalization.phpt +++ b/ext/spl/tests/ArrayObject/ArrayObject_proptable_canonicalization.phpt @@ -1,5 +1,5 @@ --TEST-- -When ArrayObject wraps an object, we should use proptable canonicalization +When ArrayObject wraps an object, we should use prop table canonicalization --FILE-- ---EXPECT-- +--EXPECTF-- +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d object(stdClass)#1 (1) { ["0"]=> int(1) diff --git a/ext/spl/tests/ArrayObject_sort_different_backing_storage.phpt b/ext/spl/tests/ArrayObject/ArrayObject_sort_different_backing_storage.phpt similarity index 73% rename from ext/spl/tests/ArrayObject_sort_different_backing_storage.phpt rename to ext/spl/tests/ArrayObject/ArrayObject_sort_different_backing_storage.phpt index 93dd6570791..34ecc1018c0 100644 --- a/ext/spl/tests/ArrayObject_sort_different_backing_storage.phpt +++ b/ext/spl/tests/ArrayObject/ArrayObject_sort_different_backing_storage.phpt @@ -29,6 +29,7 @@ var_dump($ao5); ?> --EXPECTF-- +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d object(ArrayObject)#2 (1) { ["storage":"ArrayObject":private]=> object(stdClass)#1 (2) { @@ -38,6 +39,8 @@ object(ArrayObject)#2 (1) { int(2) } } + +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d object(ArrayObject)#3 (1) { ["storage":"ArrayObject":private]=> object(ArrayObject)#2 (1) { @@ -51,6 +54,8 @@ object(ArrayObject)#3 (1) { } } +Deprecated: ArrayObject::exchangeArray(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d + Deprecated: Creation of dynamic property ArrayObject::$a is deprecated in %s on line %d Deprecated: Creation of dynamic property ArrayObject::$b is deprecated in %s on line %d diff --git a/ext/spl/tests/ArrayObject_std_props_no_recursion.phpt b/ext/spl/tests/ArrayObject/ArrayObject_std_props_no_recursion.phpt similarity index 65% rename from ext/spl/tests/ArrayObject_std_props_no_recursion.phpt rename to ext/spl/tests/ArrayObject/ArrayObject_std_props_no_recursion.phpt index 55ec57762fa..56f54844580 100644 --- a/ext/spl/tests/ArrayObject_std_props_no_recursion.phpt +++ b/ext/spl/tests/ArrayObject/ArrayObject_std_props_no_recursion.phpt @@ -16,6 +16,8 @@ var_dump((array) $c); --EXPECTF-- Deprecated: Creation of dynamic property ArrayObject::$prop is deprecated in %s on line %d +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d + Deprecated: Creation of dynamic property ArrayObject::$prop is deprecated in %s on line %d array(3) { [0]=> @@ -26,6 +28,8 @@ array(3) { int(3) } +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d + Deprecated: Creation of dynamic property ArrayObject::$prop is deprecated in %s on line %d array(1) { ["prop"]=> diff --git a/ext/spl/tests/ArrayObject_unserialize_empty_string.phpt b/ext/spl/tests/ArrayObject/ArrayObject_unserialize_empty_string.phpt similarity index 100% rename from ext/spl/tests/ArrayObject_unserialize_empty_string.phpt rename to ext/spl/tests/ArrayObject/ArrayObject_unserialize_empty_string.phpt diff --git a/ext/spl/tests/arrayIterator_ksort_basic1.phpt b/ext/spl/tests/ArrayObject/arrayIterator_ksort_basic1.phpt similarity index 100% rename from ext/spl/tests/arrayIterator_ksort_basic1.phpt rename to ext/spl/tests/ArrayObject/arrayIterator_ksort_basic1.phpt diff --git a/ext/spl/tests/arrayObject___construct_basic1.phpt b/ext/spl/tests/ArrayObject/arrayObject___construct_basic1.phpt similarity index 65% rename from ext/spl/tests/arrayObject___construct_basic1.phpt rename to ext/spl/tests/ArrayObject/arrayObject___construct_basic1.phpt index a14166c35e3..744a936276b 100644 --- a/ext/spl/tests/arrayObject___construct_basic1.phpt +++ b/ext/spl/tests/ArrayObject/arrayObject___construct_basic1.phpt @@ -16,7 +16,7 @@ var_dump(new ArrayObject(array('key1' => 'val1'))); echo "--> Nested ArrayObject argument:\n"; var_dump(new ArrayObject(new ArrayObject($a))); ?> ---EXPECT-- +--EXPECTF-- --> No arguments: object(ArrayObject)#1 (1) { ["storage":"ArrayObject":private]=> @@ -24,6 +24,8 @@ object(ArrayObject)#1 (1) { } } --> Object argument: + +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d object(ArrayObject)#2 (1) { ["storage":"ArrayObject":private]=> object(stdClass)#1 (1) { @@ -40,6 +42,10 @@ object(ArrayObject)#2 (1) { } } --> Nested ArrayObject argument: + +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d + +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d object(ArrayObject)#2 (1) { ["storage":"ArrayObject":private]=> object(ArrayObject)#3 (1) { diff --git a/ext/spl/tests/arrayObject___construct_basic2.phpt b/ext/spl/tests/ArrayObject/arrayObject___construct_basic2.phpt similarity index 85% rename from ext/spl/tests/arrayObject___construct_basic2.phpt rename to ext/spl/tests/ArrayObject/arrayObject___construct_basic2.phpt index 0d993a14e78..e1d9718b4e6 100644 --- a/ext/spl/tests/arrayObject___construct_basic2.phpt +++ b/ext/spl/tests/ArrayObject/arrayObject___construct_basic2.phpt @@ -48,6 +48,8 @@ function testAccess($c, $ao) { ?> --EXPECTF-- --> Access prop on instance of ArrayObject: + +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d - Iteration: prop=>C::prop.orig - Read: @@ -78,6 +80,8 @@ object(C)#1 (0) { } --> Access prop on instance of MyArrayObject: + +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d - Iteration: prop=>C::prop.orig - Read: diff --git a/ext/spl/tests/arrayObject___construct_basic3.phpt b/ext/spl/tests/ArrayObject/arrayObject___construct_basic3.phpt similarity index 86% rename from ext/spl/tests/arrayObject___construct_basic3.phpt rename to ext/spl/tests/ArrayObject/arrayObject___construct_basic3.phpt index 3fb4dda5a6e..135d87e6a84 100644 --- a/ext/spl/tests/arrayObject___construct_basic3.phpt +++ b/ext/spl/tests/ArrayObject/arrayObject___construct_basic3.phpt @@ -48,6 +48,8 @@ function testAccess($c, $ao) { ?> --EXPECTF-- --> Access prop on instance of ArrayObject with ArrayObject::STD_PROP_LIST: + +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d - Iteration: prop=>C::prop.orig - Read: @@ -78,6 +80,8 @@ object(C)#1 (0) { } --> Access prop on instance of MyArrayObject with ArrayObject::STD_PROP_LIST: + +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d - Iteration: prop=>C::prop.orig - Read: diff --git a/ext/spl/tests/arrayObject___construct_basic4.phpt b/ext/spl/tests/ArrayObject/arrayObject___construct_basic4.phpt similarity index 86% rename from ext/spl/tests/arrayObject___construct_basic4.phpt rename to ext/spl/tests/ArrayObject/arrayObject___construct_basic4.phpt index dd8e75af931..2aeed29178a 100644 --- a/ext/spl/tests/arrayObject___construct_basic4.phpt +++ b/ext/spl/tests/ArrayObject/arrayObject___construct_basic4.phpt @@ -48,6 +48,8 @@ function testAccess($c, $ao) { ?> --EXPECTF-- --> Access prop on instance of ArrayObject with ArrayObject::ARRAY_AS_PROPS: + +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d - Iteration: prop=>C::prop.orig - Read: @@ -76,6 +78,8 @@ object(C)#1 (0) { } --> Access prop on instance of MyArrayObject with ArrayObject::ARRAY_AS_PROPS: + +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d - Iteration: prop=>C::prop.orig - Read: diff --git a/ext/spl/tests/arrayObject___construct_basic5.phpt b/ext/spl/tests/ArrayObject/arrayObject___construct_basic5.phpt similarity index 87% rename from ext/spl/tests/arrayObject___construct_basic5.phpt rename to ext/spl/tests/ArrayObject/arrayObject___construct_basic5.phpt index e10dcd8a8d0..125f55d0637 100644 --- a/ext/spl/tests/arrayObject___construct_basic5.phpt +++ b/ext/spl/tests/ArrayObject/arrayObject___construct_basic5.phpt @@ -48,6 +48,8 @@ function testAccess($c, $ao) { ?> --EXPECTF-- --> Access prop on instance of ArrayObject with ArrayObject::STD_PROP_LIST|ArrayObject::ARRAY_AS_PROPS: + +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d - Iteration: prop=>C::prop.orig - Read: @@ -76,6 +78,8 @@ object(C)#1 (0) { } --> Access prop on instance of MyArrayObject with ArrayObject::STD_PROP_LIST|ArrayObject::ARRAY_AS_PROPS: + +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d - Iteration: prop=>C::prop.orig - Read: diff --git a/ext/spl/tests/arrayObject___construct_basic6.phpt b/ext/spl/tests/ArrayObject/arrayObject___construct_basic6.phpt similarity index 100% rename from ext/spl/tests/arrayObject___construct_basic6.phpt rename to ext/spl/tests/ArrayObject/arrayObject___construct_basic6.phpt diff --git a/ext/spl/tests/arrayObject___construct_basic7.phpt b/ext/spl/tests/ArrayObject/arrayObject___construct_basic7.phpt similarity index 71% rename from ext/spl/tests/arrayObject___construct_basic7.phpt rename to ext/spl/tests/ArrayObject/arrayObject___construct_basic7.phpt index dd10b5fb6b9..98131c8c6b4 100644 --- a/ext/spl/tests/arrayObject___construct_basic7.phpt +++ b/ext/spl/tests/ArrayObject/arrayObject___construct_basic7.phpt @@ -10,7 +10,8 @@ $ao = new ArrayObject($o); $ao->asort(); var_dump($a, $o, $ao); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d array(2) { [0]=> int(2) diff --git a/ext/spl/tests/arrayObject___construct_error1.phpt b/ext/spl/tests/ArrayObject/arrayObject___construct_error1.phpt similarity index 100% rename from ext/spl/tests/arrayObject___construct_error1.phpt rename to ext/spl/tests/ArrayObject/arrayObject___construct_error1.phpt diff --git a/ext/spl/tests/arrayObject___construct_error2.phpt b/ext/spl/tests/ArrayObject/arrayObject___construct_error2.phpt similarity index 100% rename from ext/spl/tests/arrayObject___construct_error2.phpt rename to ext/spl/tests/ArrayObject/arrayObject___construct_error2.phpt diff --git a/ext/spl/tests/arrayObject_asort_basic1.phpt b/ext/spl/tests/ArrayObject/arrayObject_asort_basic1.phpt similarity index 100% rename from ext/spl/tests/arrayObject_asort_basic1.phpt rename to ext/spl/tests/ArrayObject/arrayObject_asort_basic1.phpt diff --git a/ext/spl/tests/arrayObject_asort_basic2.phpt b/ext/spl/tests/ArrayObject/arrayObject_asort_basic2.phpt similarity index 83% rename from ext/spl/tests/arrayObject_asort_basic2.phpt rename to ext/spl/tests/ArrayObject/arrayObject_asort_basic2.phpt index 21f0dee9500..772b370ad67 100644 --- a/ext/spl/tests/arrayObject_asort_basic2.phpt +++ b/ext/spl/tests/ArrayObject/arrayObject_asort_basic2.phpt @@ -20,8 +20,10 @@ $ao1 = new ArrayObject($c); var_dump($ao1->asort()); var_dump($ao1, $c); ?> ---EXPECT-- +--EXPECTF-- *** Testing ArrayObject::asort() : basic functionality *** + +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d bool(true) object(ArrayObject)#2 (1) { ["storage":"ArrayObject":private]=> diff --git a/ext/spl/tests/arrayObject_clone_basic1.phpt b/ext/spl/tests/ArrayObject/arrayObject_clone_basic1.phpt similarity index 100% rename from ext/spl/tests/arrayObject_clone_basic1.phpt rename to ext/spl/tests/ArrayObject/arrayObject_clone_basic1.phpt diff --git a/ext/spl/tests/arrayObject_clone_basic2.phpt b/ext/spl/tests/ArrayObject/arrayObject_clone_basic2.phpt similarity index 84% rename from ext/spl/tests/arrayObject_clone_basic2.phpt rename to ext/spl/tests/ArrayObject/arrayObject_clone_basic2.phpt index b0a82ccfbc3..9cca59b60a9 100644 --- a/ext/spl/tests/arrayObject_clone_basic2.phpt +++ b/ext/spl/tests/ArrayObject/arrayObject_clone_basic2.phpt @@ -17,7 +17,8 @@ $ao1['new.ao1'] = 'new element added to ao1'; $ao2['new.ao2'] = 'new element added to ao2'; var_dump($c, $ao1, $ao2); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d object(C)#1 (3) { ["p1"]=> string(32) "new prop added to c before clone" diff --git a/ext/spl/tests/arrayObject_clone_basic3.phpt b/ext/spl/tests/ArrayObject/arrayObject_clone_basic3.phpt similarity index 86% rename from ext/spl/tests/arrayObject_clone_basic3.phpt rename to ext/spl/tests/ArrayObject/arrayObject_clone_basic3.phpt index 214a2b87b86..26e633bdd06 100644 --- a/ext/spl/tests/arrayObject_clone_basic3.phpt +++ b/ext/spl/tests/ArrayObject/arrayObject_clone_basic3.phpt @@ -23,7 +23,10 @@ $clonedOuterArrayObject['new.coAO'] = 'new element added to $clonedOuterArrayObj var_dump($wrappedObject, $innerArrayObject, $outerArrayObject, $clonedOuterArrayObject); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d + +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d object(C)#1 (5) { ["p"]=> string(9) "C::p.orig" diff --git a/ext/spl/tests/arrayObject_count_basic1.phpt b/ext/spl/tests/ArrayObject/arrayObject_count_basic1.phpt similarity index 100% rename from ext/spl/tests/arrayObject_count_basic1.phpt rename to ext/spl/tests/ArrayObject/arrayObject_count_basic1.phpt diff --git a/ext/spl/tests/arrayObject_exchangeArray_basic1.phpt b/ext/spl/tests/ArrayObject/arrayObject_exchangeArray_basic1.phpt similarity index 100% rename from ext/spl/tests/arrayObject_exchangeArray_basic1.phpt rename to ext/spl/tests/ArrayObject/arrayObject_exchangeArray_basic1.phpt diff --git a/ext/spl/tests/arrayObject_exchangeArray_basic2.phpt b/ext/spl/tests/ArrayObject/arrayObject_exchangeArray_basic2.phpt similarity index 71% rename from ext/spl/tests/arrayObject_exchangeArray_basic2.phpt rename to ext/spl/tests/ArrayObject/arrayObject_exchangeArray_basic2.phpt index 1f037e90735..4ba09cd388f 100644 --- a/ext/spl/tests/arrayObject_exchangeArray_basic2.phpt +++ b/ext/spl/tests/ArrayObject/arrayObject_exchangeArray_basic2.phpt @@ -45,6 +45,8 @@ object(ArrayObject)#%d (1) { } --> exchangeArray(normal object): + +Deprecated: ArrayObject::exchangeArray(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d string(18) "normal object prop" object(ArrayObject)#%d (1) { ["storage":"ArrayObject":private]=> @@ -55,6 +57,8 @@ object(ArrayObject)#%d (1) { } --> exchangeArray(ArrayObject): + +Deprecated: ArrayObject::exchangeArray(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d string(19) "ArrayObject element" object(ArrayObject)#%d (1) { ["storage":"ArrayObject":private]=> @@ -68,6 +72,8 @@ object(ArrayObject)#%d (1) { } --> exchangeArray(ArrayIterator): + +Deprecated: ArrayObject::exchangeArray(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d string(21) "ArrayIterator element" object(ArrayObject)#%d (1) { ["storage":"ArrayObject":private]=> @@ -81,6 +87,10 @@ object(ArrayObject)#%d (1) { } --> exchangeArray(nested ArrayObject): + +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d + +Deprecated: ArrayObject::exchangeArray(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d string(26) "nested ArrayObject element" object(ArrayObject)#%d (1) { ["storage":"ArrayObject":private]=> @@ -94,4 +104,4 @@ object(ArrayObject)#%d (1) { } } } -} +} \ No newline at end of file diff --git a/ext/spl/tests/arrayObject_exchangeArray_basic3.phpt b/ext/spl/tests/ArrayObject/arrayObject_exchangeArray_basic3.phpt similarity index 71% rename from ext/spl/tests/arrayObject_exchangeArray_basic3.phpt rename to ext/spl/tests/ArrayObject/arrayObject_exchangeArray_basic3.phpt index 49b990be8bd..8db9b016fda 100644 --- a/ext/spl/tests/arrayObject_exchangeArray_basic3.phpt +++ b/ext/spl/tests/ArrayObject/arrayObject_exchangeArray_basic3.phpt @@ -3,7 +3,7 @@ SPL: ArrayObject::exchangeArray() basic usage with object as underlying data sto --FILE-- --EXPECTF-- --> exchangeArray() with objects: + +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d + +Deprecated: ArrayObject::exchangeArray(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d + +Deprecated: Creation of dynamic property C::$addedToSwapIn is deprecated in %s on line %d + +Deprecated: Creation of dynamic property C::$addedToOriginal is deprecated in %s on line %d object(ArrayObject)#2 (1) { ["storage":"ArrayObject":private]=> object(C)#3 (2) { @@ -82,8 +90,12 @@ array(2) { --> exchangeArray() with no arg: + +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d Exception: ArrayObject::exchangeArray() expects exactly 1 argument, 0 given +Deprecated: Creation of dynamic property C::$addedToOriginal is deprecated in %s on line %d + Warning: Undefined variable $copy in %s on line %d object(ArrayObject)#2 (1) { ["storage":"ArrayObject":private]=> @@ -104,8 +116,12 @@ NULL --> exchangeArray() with bad arg type: + +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d ArrayObject::exchangeArray(): Argument #1 ($array) must be of type array, null given +Deprecated: Creation of dynamic property C::$addedToOriginal is deprecated in %s on line %d + Warning: Undefined variable $copy in %s on line %d object(ArrayObject)#3 (1) { ["storage":"ArrayObject":private]=> diff --git a/ext/spl/tests/ArrayObject/arrayObject_getFlags_basic1.phpt b/ext/spl/tests/ArrayObject/arrayObject_getFlags_basic1.phpt new file mode 100644 index 00000000000..35ae3986211 --- /dev/null +++ b/ext/spl/tests/ArrayObject/arrayObject_getFlags_basic1.phpt @@ -0,0 +1,36 @@ +--TEST-- +SPL: ArrayObject::getFlags() basic usage +--FILE-- +getFlags()); + +$ao = new ArrayObject(new ArrayObject(array(1,2,3)), ArrayObject::STD_PROP_LIST); +var_dump($ao->getFlags()); + +$ao = new ArrayObject(new ArrayIterator(new ArrayObject()), ArrayObject::ARRAY_AS_PROPS); +var_dump($ao->getFlags()); + +$ao = new ArrayObject(new ArrayObject(), ArrayObject::STD_PROP_LIST|ArrayObject::ARRAY_AS_PROPS); +var_dump($ao->getFlags()); + +$cao = clone $ao; +var_dump($cao->getFlags()); +?> +--EXPECTF-- +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d + +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d +int(0) + +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d +int(1) + +Deprecated: ArrayIterator::__construct(): Using an object as a backing array for ArrayIterator is deprecated, as it allows violating class constraints and invariants in %s on line %d + +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d +int(2) + +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d +int(3) +int(3) diff --git a/ext/spl/tests/ArrayObject/arrayObject_getFlags_basic2.phpt b/ext/spl/tests/ArrayObject/arrayObject_getFlags_basic2.phpt new file mode 100644 index 00000000000..0d0111edd1e --- /dev/null +++ b/ext/spl/tests/ArrayObject/arrayObject_getFlags_basic2.phpt @@ -0,0 +1,30 @@ +--TEST-- +SPL: ArrayObject::getFlags() - ensure flags are passed on to nested array objects and iterators. +--FILE-- +getFlags()); + +$ao2 = new ArrayObject($ao); +var_dump($ao2->getFlags()); +var_dump($ao2->getIterator()->getFlags()); + +$ai = new ArrayIterator($ao); +var_dump($ai->getFlags()); + +$ao2 = new ArrayObject($ao, 0); +var_dump($ao2->getFlags()); + +?> +--EXPECTF-- +int(3) + +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d +int(3) +int(3) + +Deprecated: ArrayIterator::__construct(): Using an object as a backing array for ArrayIterator is deprecated, as it allows violating class constraints and invariants in %s on line %d +int(3) + +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d +int(0) diff --git a/ext/spl/tests/arrayObject_getIteratorClass_basic1.phpt b/ext/spl/tests/ArrayObject/arrayObject_getIteratorClass_basic1.phpt similarity index 100% rename from ext/spl/tests/arrayObject_getIteratorClass_basic1.phpt rename to ext/spl/tests/ArrayObject/arrayObject_getIteratorClass_basic1.phpt diff --git a/ext/spl/tests/arrayObject_ksort_basic1.phpt b/ext/spl/tests/ArrayObject/arrayObject_ksort_basic1.phpt similarity index 100% rename from ext/spl/tests/arrayObject_ksort_basic1.phpt rename to ext/spl/tests/ArrayObject/arrayObject_ksort_basic1.phpt diff --git a/ext/spl/tests/arrayObject_ksort_basic2.phpt b/ext/spl/tests/ArrayObject/arrayObject_ksort_basic2.phpt similarity index 82% rename from ext/spl/tests/arrayObject_ksort_basic2.phpt rename to ext/spl/tests/ArrayObject/arrayObject_ksort_basic2.phpt index 1ac3029543d..6e64a1c64f0 100644 --- a/ext/spl/tests/arrayObject_ksort_basic2.phpt +++ b/ext/spl/tests/ArrayObject/arrayObject_ksort_basic2.phpt @@ -20,8 +20,10 @@ $ao1 = new ArrayObject($c); var_dump($ao1->ksort()); var_dump($ao1, $c); ?> ---EXPECT-- +--EXPECTF-- *** Testing ArrayObject::ksort() : basic functionality *** + +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d bool(true) object(ArrayObject)#2 (1) { ["storage":"ArrayObject":private]=> diff --git a/ext/spl/tests/arrayObject_magicMethods1.phpt b/ext/spl/tests/ArrayObject/arrayObject_magicMethods1.phpt similarity index 95% rename from ext/spl/tests/arrayObject_magicMethods1.phpt rename to ext/spl/tests/ArrayObject/arrayObject_magicMethods1.phpt index ce29beb7177..7acf8787d4a 100644 --- a/ext/spl/tests/arrayObject_magicMethods1.phpt +++ b/ext/spl/tests/ArrayObject/arrayObject_magicMethods1.phpt @@ -68,6 +68,8 @@ echo " Wrapping ArrayObject:\n"; var_dump($ao); ?> --EXPECTF-- +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d + --> Write existent, non-existent and dynamic: Original wrapped object: object(UsesMagic)#1 (5) { diff --git a/ext/spl/tests/arrayObject_magicMethods2.phpt b/ext/spl/tests/ArrayObject/arrayObject_magicMethods2.phpt similarity index 95% rename from ext/spl/tests/arrayObject_magicMethods2.phpt rename to ext/spl/tests/ArrayObject/arrayObject_magicMethods2.phpt index d28c234d54f..da3cb624b9b 100644 --- a/ext/spl/tests/arrayObject_magicMethods2.phpt +++ b/ext/spl/tests/ArrayObject/arrayObject_magicMethods2.phpt @@ -68,6 +68,8 @@ echo " Wrapping ArrayObject:\n"; var_dump($ao); ?> --EXPECTF-- +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d + --> Write existent, non-existent and dynamic: Deprecated: Creation of dynamic property ArrayObject::$a is deprecated in %s on line %d diff --git a/ext/spl/tests/arrayObject_magicMethods3.phpt b/ext/spl/tests/ArrayObject/arrayObject_magicMethods3.phpt similarity index 95% rename from ext/spl/tests/arrayObject_magicMethods3.phpt rename to ext/spl/tests/ArrayObject/arrayObject_magicMethods3.phpt index 2ff0531e01d..04ecfde195e 100644 --- a/ext/spl/tests/arrayObject_magicMethods3.phpt +++ b/ext/spl/tests/ArrayObject/arrayObject_magicMethods3.phpt @@ -68,6 +68,8 @@ echo " Wrapping ArrayObject:\n"; var_dump($ao); ?> --EXPECTF-- +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d + --> Write existent, non-existent and dynamic: Original wrapped object: object(UsesMagic)#1 (5) { diff --git a/ext/spl/tests/arrayObject_magicMethods4.phpt b/ext/spl/tests/ArrayObject/arrayObject_magicMethods4.phpt similarity index 96% rename from ext/spl/tests/arrayObject_magicMethods4.phpt rename to ext/spl/tests/ArrayObject/arrayObject_magicMethods4.phpt index e68ef1fc477..a4dabb86ec7 100644 --- a/ext/spl/tests/arrayObject_magicMethods4.phpt +++ b/ext/spl/tests/ArrayObject/arrayObject_magicMethods4.phpt @@ -71,6 +71,8 @@ echo " Wrapping ArrayObject:\n"; var_dump($ao); ?> --EXPECTF-- +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d + --> Write existent, non-existent and dynamic: Original wrapped object: object(C)#1 (5) { diff --git a/ext/spl/tests/arrayObject_magicMethods5.phpt b/ext/spl/tests/ArrayObject/arrayObject_magicMethods5.phpt similarity index 95% rename from ext/spl/tests/arrayObject_magicMethods5.phpt rename to ext/spl/tests/ArrayObject/arrayObject_magicMethods5.phpt index c0393ffea48..569d9c0bb54 100644 --- a/ext/spl/tests/arrayObject_magicMethods5.phpt +++ b/ext/spl/tests/ArrayObject/arrayObject_magicMethods5.phpt @@ -70,7 +70,9 @@ var_dump($obj); echo " Wrapping ArrayObject:\n"; var_dump($ao); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d + --> Write existent, non-existent and dynamic: In UsesMagic::__set(a,changed) In UsesMagic::__set(dynamic,new) diff --git a/ext/spl/tests/arrayObject_magicMethods6.phpt b/ext/spl/tests/ArrayObject/arrayObject_magicMethods6.phpt similarity index 96% rename from ext/spl/tests/arrayObject_magicMethods6.phpt rename to ext/spl/tests/ArrayObject/arrayObject_magicMethods6.phpt index 75151902210..ae4379c0909 100644 --- a/ext/spl/tests/arrayObject_magicMethods6.phpt +++ b/ext/spl/tests/ArrayObject/arrayObject_magicMethods6.phpt @@ -71,6 +71,8 @@ echo " Wrapping ArrayObject:\n"; var_dump($ao); ?> --EXPECTF-- +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d + --> Write existent, non-existent and dynamic: Original wrapped object: object(C)#1 (5) { diff --git a/ext/spl/tests/arrayObject_natcasesort_basic1.phpt b/ext/spl/tests/ArrayObject/arrayObject_natcasesort_basic1.phpt similarity index 100% rename from ext/spl/tests/arrayObject_natcasesort_basic1.phpt rename to ext/spl/tests/ArrayObject/arrayObject_natcasesort_basic1.phpt diff --git a/ext/spl/tests/arrayObject_natsort_basic1.phpt b/ext/spl/tests/ArrayObject/arrayObject_natsort_basic1.phpt similarity index 100% rename from ext/spl/tests/arrayObject_natsort_basic1.phpt rename to ext/spl/tests/ArrayObject/arrayObject_natsort_basic1.phpt diff --git a/ext/spl/tests/arrayObject_offsetExists_nullcheck.phpt b/ext/spl/tests/ArrayObject/arrayObject_offsetExists_nullcheck.phpt similarity index 100% rename from ext/spl/tests/arrayObject_offsetExists_nullcheck.phpt rename to ext/spl/tests/ArrayObject/arrayObject_offsetExists_nullcheck.phpt diff --git a/ext/spl/tests/arrayObject_setFlags_basic1.phpt b/ext/spl/tests/ArrayObject/arrayObject_setFlags_basic1.phpt similarity index 100% rename from ext/spl/tests/arrayObject_setFlags_basic1.phpt rename to ext/spl/tests/ArrayObject/arrayObject_setFlags_basic1.phpt diff --git a/ext/spl/tests/arrayObject_setFlags_basic2.phpt b/ext/spl/tests/ArrayObject/arrayObject_setFlags_basic2.phpt similarity index 100% rename from ext/spl/tests/arrayObject_setFlags_basic2.phpt rename to ext/spl/tests/ArrayObject/arrayObject_setFlags_basic2.phpt diff --git a/ext/spl/tests/arrayObject_setIteratorClass_error1.phpt b/ext/spl/tests/ArrayObject/arrayObject_setIteratorClass_error1.phpt similarity index 100% rename from ext/spl/tests/arrayObject_setIteratorClass_error1.phpt rename to ext/spl/tests/ArrayObject/arrayObject_setIteratorClass_error1.phpt diff --git a/ext/spl/tests/arrayObject_uasort_basic1.phpt b/ext/spl/tests/ArrayObject/arrayObject_uasort_basic1.phpt similarity index 100% rename from ext/spl/tests/arrayObject_uasort_basic1.phpt rename to ext/spl/tests/ArrayObject/arrayObject_uasort_basic1.phpt diff --git a/ext/spl/tests/arrayObject_uasort_error1.phpt b/ext/spl/tests/ArrayObject/arrayObject_uasort_error1.phpt similarity index 100% rename from ext/spl/tests/arrayObject_uasort_error1.phpt rename to ext/spl/tests/ArrayObject/arrayObject_uasort_error1.phpt diff --git a/ext/spl/tests/arrayObject_uksort_basic1.phpt b/ext/spl/tests/ArrayObject/arrayObject_uksort_basic1.phpt similarity index 100% rename from ext/spl/tests/arrayObject_uksort_basic1.phpt rename to ext/spl/tests/ArrayObject/arrayObject_uksort_basic1.phpt diff --git a/ext/spl/tests/arrayObject_uksort_error1.phpt b/ext/spl/tests/ArrayObject/arrayObject_uksort_error1.phpt similarity index 100% rename from ext/spl/tests/arrayObject_uksort_error1.phpt rename to ext/spl/tests/ArrayObject/arrayObject_uksort_error1.phpt diff --git a/ext/spl/tests/array_001.phpt b/ext/spl/tests/ArrayObject/array_001.phpt similarity index 100% rename from ext/spl/tests/array_001.phpt rename to ext/spl/tests/ArrayObject/array_001.phpt diff --git a/ext/spl/tests/array_002.phpt b/ext/spl/tests/ArrayObject/array_002.phpt similarity index 78% rename from ext/spl/tests/array_002.phpt rename to ext/spl/tests/ArrayObject/array_002.phpt index 94559f5bf75..a305770edf9 100644 --- a/ext/spl/tests/array_002.phpt +++ b/ext/spl/tests/ArrayObject/array_002.phpt @@ -18,6 +18,7 @@ var_dump($arrayObject); ?> --EXPECTF-- +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d object(ArrayObject)#%d (1) { ["storage":"ArrayObject":private]=> object(ArrayObject)#1 (1) { diff --git a/ext/spl/tests/array_003.phpt b/ext/spl/tests/ArrayObject/array_003.phpt similarity index 84% rename from ext/spl/tests/array_003.phpt rename to ext/spl/tests/ArrayObject/array_003.phpt index 3ca23f09dc7..38db0562504 100644 --- a/ext/spl/tests/array_003.phpt +++ b/ext/spl/tests/ArrayObject/array_003.phpt @@ -35,7 +35,7 @@ foreach($test as $key => $val) } ?> ---EXPECT-- +--EXPECTF-- test Object ( [pub] => public @@ -44,6 +44,8 @@ test Object [imp] => implicit [dyn] => dynamic ) + +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d ArrayObject Object ( [storage:ArrayObject:private] => test Object diff --git a/ext/spl/tests/array_004.phpt b/ext/spl/tests/ArrayObject/array_004.phpt similarity index 100% rename from ext/spl/tests/array_004.phpt rename to ext/spl/tests/ArrayObject/array_004.phpt diff --git a/ext/spl/tests/array_005.phpt b/ext/spl/tests/ArrayObject/array_005.phpt similarity index 100% rename from ext/spl/tests/array_005.phpt rename to ext/spl/tests/ArrayObject/array_005.phpt diff --git a/ext/spl/tests/array_006.phpt b/ext/spl/tests/ArrayObject/array_006.phpt similarity index 100% rename from ext/spl/tests/array_006.phpt rename to ext/spl/tests/ArrayObject/array_006.phpt diff --git a/ext/spl/tests/array_007.phpt b/ext/spl/tests/ArrayObject/array_007.phpt similarity index 78% rename from ext/spl/tests/array_007.phpt rename to ext/spl/tests/ArrayObject/array_007.phpt index 3cdd40a1dbc..de492257c65 100644 --- a/ext/spl/tests/array_007.phpt +++ b/ext/spl/tests/ArrayObject/array_007.phpt @@ -39,7 +39,7 @@ foreach($test as $key => $val) } ?> ---EXPECT-- +--EXPECTF-- test Object ( [pub] => public @@ -48,6 +48,8 @@ test Object [imp] => implicit [dyn] => dynamic ) + +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d ArrayIterator Object ( [storage:ArrayIterator:private] => ArrayObject Object @@ -64,6 +66,8 @@ ArrayIterator Object ) ) + +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d pub => public imp => implicit dyn => dynamic diff --git a/ext/spl/tests/array_008.phpt b/ext/spl/tests/ArrayObject/array_008.phpt similarity index 100% rename from ext/spl/tests/array_008.phpt rename to ext/spl/tests/ArrayObject/array_008.phpt diff --git a/ext/spl/tests/array_009.phpt b/ext/spl/tests/ArrayObject/array_009.phpt similarity index 100% rename from ext/spl/tests/array_009.phpt rename to ext/spl/tests/ArrayObject/array_009.phpt diff --git a/ext/spl/tests/array_009a.phpt b/ext/spl/tests/ArrayObject/array_009a.phpt similarity index 100% rename from ext/spl/tests/array_009a.phpt rename to ext/spl/tests/ArrayObject/array_009a.phpt diff --git a/ext/spl/tests/array_010.phpt b/ext/spl/tests/ArrayObject/array_010.phpt similarity index 100% rename from ext/spl/tests/array_010.phpt rename to ext/spl/tests/ArrayObject/array_010.phpt diff --git a/ext/spl/tests/array_011.phpt b/ext/spl/tests/ArrayObject/array_011.phpt similarity index 100% rename from ext/spl/tests/array_011.phpt rename to ext/spl/tests/ArrayObject/array_011.phpt diff --git a/ext/spl/tests/array_012.phpt b/ext/spl/tests/ArrayObject/array_012.phpt similarity index 79% rename from ext/spl/tests/array_012.phpt rename to ext/spl/tests/ArrayObject/array_012.phpt index 5d5993d9369..f3b0fa9813b 100644 --- a/ext/spl/tests/array_012.phpt +++ b/ext/spl/tests/ArrayObject/array_012.phpt @@ -39,7 +39,7 @@ foreach($it as $key => $val) var_dump($it->count()); ?> ---EXPECT-- +--EXPECTF-- ===Array=== int(3) zero=>0 @@ -50,6 +50,8 @@ two=>2 int(3) int(3) ===Object=== + +Deprecated: ArrayIterator::__construct(): Using an object as a backing array for ArrayIterator is deprecated, as it allows violating class constraints and invariants in %s on line %d int(3) zero=>0 int(3) diff --git a/ext/spl/tests/array_013.phpt b/ext/spl/tests/ArrayObject/array_013.phpt similarity index 87% rename from ext/spl/tests/array_013.phpt rename to ext/spl/tests/ArrayObject/array_013.phpt index 9ad11c8f38c..01097bac04d 100644 --- a/ext/spl/tests/array_013.phpt +++ b/ext/spl/tests/ArrayObject/array_013.phpt @@ -70,6 +70,8 @@ var_dump($o->{0}); /* doesn't wotk anyway */ 3=>three 4=>four ===Object=== + +Deprecated: ArrayIterator::__construct(): Using an object as a backing array for ArrayIterator is deprecated, as it allows violating class constraints and invariants in %s on line %d zero=>0 one=>1 two=>2 diff --git a/ext/spl/tests/array_014.phpt b/ext/spl/tests/ArrayObject/array_014.phpt similarity index 100% rename from ext/spl/tests/array_014.phpt rename to ext/spl/tests/ArrayObject/array_014.phpt diff --git a/ext/spl/tests/array_015.phpt b/ext/spl/tests/ArrayObject/array_015.phpt similarity index 100% rename from ext/spl/tests/array_015.phpt rename to ext/spl/tests/ArrayObject/array_015.phpt diff --git a/ext/spl/tests/array_016.phpt b/ext/spl/tests/ArrayObject/array_016.phpt similarity index 100% rename from ext/spl/tests/array_016.phpt rename to ext/spl/tests/ArrayObject/array_016.phpt diff --git a/ext/spl/tests/array_017.phpt b/ext/spl/tests/ArrayObject/array_017.phpt similarity index 88% rename from ext/spl/tests/array_017.phpt rename to ext/spl/tests/ArrayObject/array_017.phpt index ba4842dce20..2a80386b6f7 100644 --- a/ext/spl/tests/array_017.phpt +++ b/ext/spl/tests/ArrayObject/array_017.phpt @@ -177,6 +177,8 @@ array(3) { ArrayObjectEx::show() ArrayObjectEx::getIterator() ArrayIteratorEx::__construct() + +Deprecated: ArrayIterator::__construct(): Using an object as a backing array for ArrayIterator is deprecated, as it allows violating class constraints and invariants in %s on line %d ArrayIteratorEx::dump() array(3) { ["Flags"]=> @@ -245,6 +247,8 @@ array(1) { ===FOREACH=== ArrayObjectEx::getIterator() ArrayIteratorEx::__construct() + +Deprecated: ArrayIterator::__construct(): Using an object as a backing array for ArrayIterator is deprecated, as it allows violating class constraints and invariants in %s on line %d ArrayIteratorEx::dump() array(3) { ["Flags"]=> @@ -366,6 +370,8 @@ array(3) { ArrayObjectEx::show() ArrayObjectEx::getIterator() ArrayIteratorEx::__construct() + +Deprecated: ArrayIterator::__construct(): Using an object as a backing array for ArrayIterator is deprecated, as it allows violating class constraints and invariants in %s on line %d ArrayIteratorEx::dump() array(3) { ["Flags"]=> @@ -434,6 +440,8 @@ array(1) { ===FOREACH=== ArrayObjectEx::getIterator() ArrayIteratorEx::__construct() + +Deprecated: ArrayIterator::__construct(): Using an object as a backing array for ArrayIterator is deprecated, as it allows violating class constraints and invariants in %s on line %d ArrayIteratorEx::dump() array(3) { ["Flags"]=> @@ -512,6 +520,8 @@ int(1) bool(true) #####EXCHANGE##### ArrayObjectEx::exchange() + +Deprecated: ArrayObject::exchangeArray(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d ===CHECK=== ArrayObjectEx::setFlags(0) ArrayObjectEx::dump() @@ -548,6 +558,8 @@ array(3) { ArrayObjectEx::show() ArrayObjectEx::getIterator() ArrayIteratorEx::__construct() + +Deprecated: ArrayIterator::__construct(): Using an object as a backing array for ArrayIterator is deprecated, as it allows violating class constraints and invariants in %s on line %d ArrayIteratorEx::dump() array(3) { ["Flags"]=> @@ -607,6 +619,8 @@ array(1) { ===FOREACH=== ArrayObjectEx::getIterator() ArrayIteratorEx::__construct() + +Deprecated: ArrayIterator::__construct(): Using an object as a backing array for ArrayIterator is deprecated, as it allows violating class constraints and invariants in %s on line %d ArrayIteratorEx::dump() array(3) { ["Flags"]=> @@ -710,6 +724,8 @@ array(3) { ArrayObjectEx::show() ArrayObjectEx::getIterator() ArrayIteratorEx::__construct() + +Deprecated: ArrayIterator::__construct(): Using an object as a backing array for ArrayIterator is deprecated, as it allows violating class constraints and invariants in %s on line %d ArrayIteratorEx::dump() array(3) { ["Flags"]=> @@ -769,6 +785,8 @@ array(1) { ===FOREACH=== ArrayObjectEx::getIterator() ArrayIteratorEx::__construct() + +Deprecated: ArrayIterator::__construct(): Using an object as a backing array for ArrayIterator is deprecated, as it allows violating class constraints and invariants in %s on line %d ArrayIteratorEx::dump() array(3) { ["Flags"]=> diff --git a/ext/spl/tests/array_018.phpt b/ext/spl/tests/ArrayObject/array_018.phpt similarity index 100% rename from ext/spl/tests/array_018.phpt rename to ext/spl/tests/ArrayObject/array_018.phpt diff --git a/ext/spl/tests/array_019.phpt b/ext/spl/tests/ArrayObject/array_019.phpt similarity index 100% rename from ext/spl/tests/array_019.phpt rename to ext/spl/tests/ArrayObject/array_019.phpt diff --git a/ext/spl/tests/array_020.phpt b/ext/spl/tests/ArrayObject/array_020.phpt similarity index 100% rename from ext/spl/tests/array_020.phpt rename to ext/spl/tests/ArrayObject/array_020.phpt diff --git a/ext/spl/tests/array_021.phpt b/ext/spl/tests/ArrayObject/array_021.phpt similarity index 100% rename from ext/spl/tests/array_021.phpt rename to ext/spl/tests/ArrayObject/array_021.phpt diff --git a/ext/spl/tests/array_022.phpt b/ext/spl/tests/ArrayObject/array_022.phpt similarity index 72% rename from ext/spl/tests/array_022.phpt rename to ext/spl/tests/ArrayObject/array_022.phpt index f7407bf602c..4e8c94fd118 100644 --- a/ext/spl/tests/array_022.phpt +++ b/ext/spl/tests/ArrayObject/array_022.phpt @@ -45,6 +45,8 @@ var_dump($b); ?> --EXPECTF-- ==ArrayObject=== + +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d object(MyArrayObject)#%d (1) { ["bar"]=> string(3) "baz" @@ -56,6 +58,8 @@ object(MyArrayObject)#%d (2) { string(3) "Foo" } ==ArrayIterator=== + +Deprecated: ArrayIterator::__construct(): Using an object as a backing array for ArrayIterator is deprecated, as it allows violating class constraints and invariants in %s on line %d object(MyArrayIterator)#%d (1) { ["bar"]=> string(3) "baz" diff --git a/ext/spl/tests/array_023.phpt b/ext/spl/tests/ArrayObject/array_023.phpt similarity index 100% rename from ext/spl/tests/array_023.phpt rename to ext/spl/tests/ArrayObject/array_023.phpt diff --git a/ext/spl/tests/array_024.phpt b/ext/spl/tests/ArrayObject/array_024.phpt similarity index 100% rename from ext/spl/tests/array_024.phpt rename to ext/spl/tests/ArrayObject/array_024.phpt diff --git a/ext/spl/tests/array_025.phpt b/ext/spl/tests/ArrayObject/array_025.phpt similarity index 69% rename from ext/spl/tests/array_025.phpt rename to ext/spl/tests/ArrayObject/array_025.phpt index d64f8f04c1e..4bd4c434f48 100644 --- a/ext/spl/tests/array_025.phpt +++ b/ext/spl/tests/ArrayObject/array_025.phpt @@ -10,7 +10,10 @@ print_r($obj1); echo "$s\n"; print_r($obj2); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d + +Deprecated: ArrayObject::__unserialize(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d ArrayObject Object ( [storage:ArrayObject:private] => ArrayObject Object diff --git a/ext/spl/tests/array_026.phpt b/ext/spl/tests/ArrayObject/array_026.phpt similarity index 100% rename from ext/spl/tests/array_026.phpt rename to ext/spl/tests/ArrayObject/array_026.phpt diff --git a/ext/spl/tests/array_027.phpt b/ext/spl/tests/ArrayObject/array_027.phpt similarity index 100% rename from ext/spl/tests/array_027.phpt rename to ext/spl/tests/ArrayObject/array_027.phpt diff --git a/ext/spl/tests/array_028.phpt b/ext/spl/tests/ArrayObject/array_028.phpt similarity index 66% rename from ext/spl/tests/array_028.phpt rename to ext/spl/tests/ArrayObject/array_028.phpt index 1adcdd3f907..1e422fe2f99 100644 --- a/ext/spl/tests/array_028.phpt +++ b/ext/spl/tests/ArrayObject/array_028.phpt @@ -21,7 +21,9 @@ foreach ($obj as $v) { var_dump($v); } ?> ---EXPECT-- +--EXPECTF-- string(3) "bar" string(3) "bar" + +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d string(3) "bar" diff --git a/ext/spl/tests/bug31346.phpt b/ext/spl/tests/ArrayObject/bug31346.phpt similarity index 54% rename from ext/spl/tests/bug31346.phpt rename to ext/spl/tests/ArrayObject/bug31346.phpt index b2d29905ac7..a1088dfd013 100644 --- a/ext/spl/tests/bug31346.phpt +++ b/ext/spl/tests/ArrayObject/bug31346.phpt @@ -14,5 +14,6 @@ $i->next(); ?> ===DONE=== ---EXPECT-- +--EXPECTF-- +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d ===DONE=== diff --git a/ext/spl/tests/bug38618.phpt b/ext/spl/tests/ArrayObject/bug38618.phpt similarity index 69% rename from ext/spl/tests/bug38618.phpt rename to ext/spl/tests/ArrayObject/bug38618.phpt index 71a09111a4b..5a865f12d63 100644 --- a/ext/spl/tests/bug38618.phpt +++ b/ext/spl/tests/ArrayObject/bug38618.phpt @@ -84,14 +84,22 @@ test_array($array, 'Protected Property'); test_array($array, 'Public Property New', RecursiveArrayIterator::CHILD_ARRAYS_ONLY); test_array($array, 'Protected Property New', RecursiveArrayIterator::CHILD_ARRAYS_ONLY); ?> ---EXPECT-- +--EXPECTF-- ===Default with array=== 1 => apple 1 => grape ===Public Property=== + +Deprecated: ArrayIterator::__construct(): Using an object as a backing array for ArrayIterator is deprecated, as it allows violating class constraints and invariants in %s on line %d title => apple + +Deprecated: ArrayIterator::__construct(): Using an object as a backing array for ArrayIterator is deprecated, as it allows violating class constraints and invariants in %s on line %d title => grape ===Protected Property=== + +Deprecated: ArrayIterator::__construct(): Using an object as a backing array for ArrayIterator is deprecated, as it allows violating class constraints and invariants in %s on line %d + +Deprecated: ArrayIterator::__construct(): Using an object as a backing array for ArrayIterator is deprecated, as it allows violating class constraints and invariants in %s on line %d ===Public Property New=== 1 => apple 1 => grape diff --git a/ext/spl/tests/bug41691.phpt b/ext/spl/tests/ArrayObject/bug41691.phpt similarity index 70% rename from ext/spl/tests/bug41691.phpt rename to ext/spl/tests/ArrayObject/bug41691.phpt index 93af430b488..c808d59c202 100644 --- a/ext/spl/tests/bug41691.phpt +++ b/ext/spl/tests/ArrayObject/bug41691.phpt @@ -17,7 +17,8 @@ var_dump($a->exchangeArray(array('a'=>1,'b'=>1,'c'=>1))); echo "Done\n"; ?> ---EXPECT-- +--EXPECTF-- +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d array(3) { ["a"]=> NULL diff --git a/ext/spl/tests/bug44615.phpt b/ext/spl/tests/ArrayObject/bug44615.phpt similarity index 76% rename from ext/spl/tests/bug44615.phpt rename to ext/spl/tests/ArrayObject/bug44615.phpt index 0b9aa82bc30..3ac30192170 100644 --- a/ext/spl/tests/bug44615.phpt +++ b/ext/spl/tests/ArrayObject/bug44615.phpt @@ -20,7 +20,7 @@ foreach (new RecursiveIteratorIterator($rai) as $t) { var_dump($t); } ?> ---EXPECT-- +--EXPECTF-- string(1) "z" object(stdClass)#1 (0) { } @@ -28,5 +28,7 @@ string(1) "q" string(1) "s" Second: string(1) "z" + +Deprecated: ArrayIterator::__construct(): Using an object as a backing array for ArrayIterator is deprecated, as it allows violating class constraints and invariants in %s on line %d string(1) "q" string(1) "s" diff --git a/ext/spl/tests/bug45614.phpt b/ext/spl/tests/ArrayObject/bug45614.phpt similarity index 87% rename from ext/spl/tests/bug45614.phpt rename to ext/spl/tests/ArrayObject/bug45614.phpt index 8c688555d37..04c46381553 100644 --- a/ext/spl/tests/bug45614.phpt +++ b/ext/spl/tests/ArrayObject/bug45614.phpt @@ -39,7 +39,8 @@ $ai->rewind(); $ai->seek(0); showFirstTwoItems($ai); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d --> Show the first two items: pub1 => public1 pub2 => public2 diff --git a/ext/spl/tests/bug54323.phpt b/ext/spl/tests/ArrayObject/bug54323.phpt similarity index 74% rename from ext/spl/tests/bug54323.phpt rename to ext/spl/tests/ArrayObject/bug54323.phpt index 7431c9c4734..fa1e64f4947 100644 --- a/ext/spl/tests/bug54323.phpt +++ b/ext/spl/tests/ArrayObject/bug54323.phpt @@ -18,6 +18,8 @@ function testAccess($c, $ao) { } ?> --EXPECTF-- +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d + Warning: Undefined property: C::$prop in %s on line %d Warning: Undefined array key "prop" in %s on line %d diff --git a/ext/spl/tests/bug62672.phpt b/ext/spl/tests/ArrayObject/bug62672.phpt similarity index 71% rename from ext/spl/tests/bug62672.phpt rename to ext/spl/tests/ArrayObject/bug62672.phpt index ec40ee69550..2d70ca71a1b 100644 --- a/ext/spl/tests/bug62672.phpt +++ b/ext/spl/tests/ArrayObject/bug62672.phpt @@ -28,5 +28,6 @@ $obj = new ObjB(new ArrayObject()); var_dump($obj == unserialize(serialize($obj))); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: ArrayIterator::__unserialize(): Using an object as a backing array for ArrayIterator is deprecated, as it allows violating class constraints and invariants in %s on line %d bool(true) diff --git a/ext/spl/tests/ArrayObject/bug69845.phpt b/ext/spl/tests/ArrayObject/bug69845.phpt new file mode 100644 index 00000000000..6554e290e03 --- /dev/null +++ b/ext/spl/tests/ArrayObject/bug69845.phpt @@ -0,0 +1,16 @@ +--TEST-- +Fixed bug #69845 (ArrayObject with ARRAY_AS_PROPS broken) +--FILE-- +itemType = 'bulletin'; + var_dump(!is_null($data['itemType'])); +} +?> +--EXPECTF-- +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d +bool(true) + +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d +bool(true) diff --git a/ext/spl/tests/bug70155.phpt b/ext/spl/tests/ArrayObject/bug70155.phpt similarity index 75% rename from ext/spl/tests/bug70155.phpt rename to ext/spl/tests/ArrayObject/bug70155.phpt index a609205aca2..27521015c48 100644 --- a/ext/spl/tests/bug70155.phpt +++ b/ext/spl/tests/ArrayObject/bug70155.phpt @@ -9,6 +9,8 @@ $data = unserialize($exploit); var_dump($data); ?> --EXPECTF-- +Deprecated: ArrayObject::unserialize(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d + Deprecated: Creation of dynamic property ArrayObject::$0 is deprecated in %s on line %d Fatal error: Uncaught InvalidArgumentException: Overloaded object of type DateInterval is not compatible with ArrayObject in %s diff --git a/ext/spl/tests/bug73209.phpt b/ext/spl/tests/ArrayObject/bug73209.phpt similarity index 74% rename from ext/spl/tests/bug73209.phpt rename to ext/spl/tests/ArrayObject/bug73209.phpt index 73839409366..7da582b1352 100644 --- a/ext/spl/tests/bug73209.phpt +++ b/ext/spl/tests/ArrayObject/bug73209.phpt @@ -19,7 +19,8 @@ foreach($iterator as $k=>$v) { } ?> ---EXPECT-- +--EXPECTF-- +Deprecated: ArrayIterator::__construct(): Using an object as a backing array for ArrayIterator is deprecated, as it allows violating class constraints and invariants in %s on line %d Expect to see all keys in ->props here: props hello diff --git a/ext/spl/tests/bug74669.phpt b/ext/spl/tests/ArrayObject/bug74669.phpt similarity index 76% rename from ext/spl/tests/bug74669.phpt rename to ext/spl/tests/ArrayObject/bug74669.phpt index 597e694296d..17f622aaaf9 100644 --- a/ext/spl/tests/bug74669.phpt +++ b/ext/spl/tests/ArrayObject/bug74669.phpt @@ -93,13 +93,20 @@ var_dump($selfArray['foo']); ?> --EXPECTF-- -0 => test1 -1 => test2 +Deprecated: ArrayIterator::__unserialize(): Using an object as a backing array for ArrayIterator is deprecated, as it allows violating class constraints and invariants in %s on line %d 0 => test1 1 => test2 +Deprecated: ArrayIterator::__unserialize(): Using an object as a backing array for ArrayIterator is deprecated, as it allows violating class constraints and invariants in %s on line %d +0 => test1 +1 => test2 + +Deprecated: ArrayObject::unserialize(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d + Warning: Undefined array key "foo" in %s on line %d NULL + +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d object(SelfArray)#9 (1) { ["foo"]=> string(3) "bar" diff --git a/ext/spl/tests/gh10519.phpt b/ext/spl/tests/ArrayObject/gh10519.phpt similarity index 88% rename from ext/spl/tests/gh10519.phpt rename to ext/spl/tests/ArrayObject/gh10519.phpt index 1f7572d6e8c..5ef7fb3144f 100644 --- a/ext/spl/tests/gh10519.phpt +++ b/ext/spl/tests/ArrayObject/gh10519.phpt @@ -62,7 +62,8 @@ $example->bugySetMethod(5, 'must be here'); var_dump(json_encode($example)); var_dump(json_encode($b)); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: ArrayIterator::__construct(): Using an object as a backing array for ArrayIterator is deprecated, as it allows violating class constraints and invariants in %s on line %d string(51) "{"test":{"a":{"2":"","3":"","4":"","5":"in here"}}}" string(51) "{"test":{"a":{"2":"","3":"","4":"","5":"in here"}}}" string(56) "{"test":{"b":{"2":"","3":"","4":"","5":"must be here"}}}" diff --git a/ext/spl/tests/gh11178.phpt b/ext/spl/tests/ArrayObject/gh11178.phpt similarity index 69% rename from ext/spl/tests/gh11178.phpt rename to ext/spl/tests/ArrayObject/gh11178.phpt index 3732c57a59d..91ac55d6f81 100644 --- a/ext/spl/tests/gh11178.phpt +++ b/ext/spl/tests/ArrayObject/gh11178.phpt @@ -21,7 +21,8 @@ foreach ($obj as $k => &$v) { var_dump($obj); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: ArrayIterator::__construct(): Using an object as a backing array for ArrayIterator is deprecated, as it allows violating class constraints and invariants in %s on line %d object(A)#1 (1) { ["x"]=> &int(3) diff --git a/ext/spl/tests/gh15833_1.phpt b/ext/spl/tests/ArrayObject/gh15833_1.phpt similarity index 71% rename from ext/spl/tests/gh15833_1.phpt rename to ext/spl/tests/ArrayObject/gh15833_1.phpt index d658a770e80..5ee4b69e325 100644 --- a/ext/spl/tests/gh15833_1.phpt +++ b/ext/spl/tests/ArrayObject/gh15833_1.phpt @@ -17,6 +17,7 @@ var_dump($recursiveArrayIterator->current()); $recursiveArrayIterator->next(); var_dump($recursiveArrayIterator->current()); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: ArrayIterator::__construct(): Using an object as a backing array for ArrayIterator is deprecated, as it allows violating class constraints and invariants in %s on line %d int(1) NULL diff --git a/ext/spl/tests/gh15833_2.phpt b/ext/spl/tests/ArrayObject/gh15833_2.phpt similarity index 81% rename from ext/spl/tests/gh15833_2.phpt rename to ext/spl/tests/ArrayObject/gh15833_2.phpt index 8f30921741f..5d7721e25dd 100644 --- a/ext/spl/tests/gh15833_2.phpt +++ b/ext/spl/tests/ArrayObject/gh15833_2.phpt @@ -34,7 +34,8 @@ try { echo $e->getMessage(), "\n"; } ?> ---EXPECT-- +--EXPECTF-- +Deprecated: ArrayIterator::__construct(): Using an object as a backing array for ArrayIterator is deprecated, as it allows violating class constraints and invariants in %s on line %d nope 0 nope 1 nope 2 diff --git a/ext/spl/tests/gh15918.phpt b/ext/spl/tests/ArrayObject/gh15918.phpt similarity index 61% rename from ext/spl/tests/gh15918.phpt rename to ext/spl/tests/ArrayObject/gh15918.phpt index b26ff8adfc1..5efdb887f9b 100644 --- a/ext/spl/tests/gh15918.phpt +++ b/ext/spl/tests/ArrayObject/gh15918.phpt @@ -9,5 +9,6 @@ try { echo $e->getMessage(), "\n"; } ?> ---EXPECT-- +--EXPECTF-- +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d Overloaded object of type SplFixedArray is not compatible with ArrayObject diff --git a/ext/spl/tests/gh16646.phpt b/ext/spl/tests/ArrayObject/gh16646.phpt similarity index 71% rename from ext/spl/tests/gh16646.phpt rename to ext/spl/tests/ArrayObject/gh16646.phpt index b6cb503d8ed..f572346ea5d 100644 --- a/ext/spl/tests/gh16646.phpt +++ b/ext/spl/tests/ArrayObject/gh16646.phpt @@ -23,7 +23,8 @@ unset($arr["b"]); var_dump($arr); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d C::__destruct object(ArrayObject)#1 (1) { ["storage":"ArrayObject":private]=> diff --git a/ext/spl/tests/gh16646_2.phpt b/ext/spl/tests/ArrayObject/gh16646_2.phpt similarity index 67% rename from ext/spl/tests/gh16646_2.phpt rename to ext/spl/tests/ArrayObject/gh16646_2.phpt index d0065835008..035087fbe22 100644 --- a/ext/spl/tests/gh16646_2.phpt +++ b/ext/spl/tests/ArrayObject/gh16646_2.phpt @@ -16,7 +16,8 @@ $arr->exchangeArray([]); var_dump($arr); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d C::__destruct object(ArrayObject)#1 (1) { ["storage":"ArrayObject":private]=> diff --git a/ext/spl/tests/ArrayObject/property_hooks.phpt b/ext/spl/tests/ArrayObject/property_hooks.phpt index c0b2a372ebe..dfed649e7c6 100644 --- a/ext/spl/tests/ArrayObject/property_hooks.phpt +++ b/ext/spl/tests/ArrayObject/property_hooks.phpt @@ -63,6 +63,7 @@ var_dump($o->username); ?> --EXPECTF-- +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d Check object properties directly string(5) "FIRST" string(4) "last" diff --git a/ext/spl/tests/SplObjectStorage/SplObjectStorage_coalesce.phpt b/ext/spl/tests/SplObjectStorage/SplObjectStorage_coalesce.phpt index 5a89b46be6b..d4075018d34 100644 --- a/ext/spl/tests/SplObjectStorage/SplObjectStorage_coalesce.phpt +++ b/ext/spl/tests/SplObjectStorage/SplObjectStorage_coalesce.phpt @@ -19,15 +19,17 @@ var_dump(isset($s[$o2])); var_dump(empty($s[$o2])); $s[$o2] = null; var_dump($s[$o2] ?? new stdClass()); -echo "check isset/empty/contains for null. offsetExists returns true as long as the entry is there.\n"; +echo "check isset/empty/contains/offsetExists for null. offsetExists returns true as long as the entry is there.\n"; var_dump(isset($s[$o2])); var_dump(empty($s[$o2])); var_dump($s->contains($o2)); -echo "check isset/empty/contains for false.\n"; +var_dump($s->offsetExists($o2)); +echo "check isset/empty/contains/offsetExists for false.\n"; $s[$o2] = false; var_dump(isset($s[$o2])); var_dump(empty($s[$o2])); var_dump($s->contains($o2)); +var_dump($s->offsetExists($o2)); try { $s['invalid'] = 123; } catch (Error $e) { @@ -56,18 +58,24 @@ bool(false) bool(true) object(stdClass)#4 (0) { } -check isset/empty/contains for null. offsetExists returns true as long as the entry is there. +check isset/empty/contains/offsetExists for null. offsetExists returns true as long as the entry is there. bool(true) bool(true) + +Deprecated: Method SplObjectStorage::contains() is deprecated since 8.5, use method SplObjectStorage::offsetExists() instead in %s on line %d bool(true) -check isset/empty/contains for false. bool(true) +check isset/empty/contains/offsetExists for false. +bool(true) +bool(true) + +Deprecated: Method SplObjectStorage::contains() is deprecated since 8.5, use method SplObjectStorage::offsetExists() instead in %s on line %d bool(true) bool(true) TypeError: SplObjectStorage::offsetSet(): Argument #1 ($object) must be of type object, string given TypeError: SplObjectStorage::offsetExists(): Argument #1 ($object) must be of type object, string given -Notice: Indirect modification of overloaded element of SplObjectStorage has no effect in %s on line 38 +Notice: Indirect modification of overloaded element of SplObjectStorage has no effect in %s on line %d object(SplObjectStorage)#1 (1) { ["storage":"SplObjectStorage":private]=> array(2) { diff --git a/ext/spl/tests/SplObjectStorage/SplObjectStorage_removeAllExcept_basic.phpt b/ext/spl/tests/SplObjectStorage/SplObjectStorage_removeAllExcept_basic.phpt index a6059da2958..fa7fdf367fa 100644 --- a/ext/spl/tests/SplObjectStorage/SplObjectStorage_removeAllExcept_basic.phpt +++ b/ext/spl/tests/SplObjectStorage/SplObjectStorage_removeAllExcept_basic.phpt @@ -10,16 +10,16 @@ $b = (object) 'b'; $c = (object) 'c'; $foo = new SplObjectStorage; -$foo->attach($a); -$foo->attach($b); +$foo->offsetSet($a); +$foo->offsetSet($b); $bar = new SplObjectStorage; -$bar->attach($b); -$bar->attach($c); +$bar->offsetSet($b); +$bar->offsetSet($c); $foo->removeAllExcept($bar); -var_dump($foo->contains($a)); -var_dump($foo->contains($b)); +var_dump($foo->offsetExists($a)); +var_dump($foo->offsetExists($b)); ?> --EXPECT-- diff --git a/ext/spl/tests/SplObjectStorage_seek.phpt b/ext/spl/tests/SplObjectStorage/SplObjectStorage_seek.phpt similarity index 97% rename from ext/spl/tests/SplObjectStorage_seek.phpt rename to ext/spl/tests/SplObjectStorage/SplObjectStorage_seek.phpt index f51a285d060..ce21b2a621f 100644 --- a/ext/spl/tests/SplObjectStorage_seek.phpt +++ b/ext/spl/tests/SplObjectStorage/SplObjectStorage_seek.phpt @@ -64,8 +64,8 @@ var_dump($storage->current()); echo "--- With holes cases ---\n"; -$storage->detach($b); -$storage->detach($d); +$storage->offsetUnset($b); +$storage->offsetUnset($d); foreach (range(0, 2) as $index) { $storage->seek($index); diff --git a/ext/spl/tests/SplObjectStorage/bug49263.phpt b/ext/spl/tests/SplObjectStorage/bug49263.phpt index 23bd0b272a7..a8088f18079 100644 --- a/ext/spl/tests/SplObjectStorage/bug49263.phpt +++ b/ext/spl/tests/SplObjectStorage/bug49263.phpt @@ -7,8 +7,8 @@ $o2 = new stdClass; $s = new SplObjectStorage(); -$s->attach($o1, array('prev' => 2, 'next' => $o2)); -$s->attach($o2, array('prev' => $o1)); +$s->offsetSet($o1, array('prev' => 2, 'next' => $o2)); +$s->offsetSet($o2, array('prev' => $o1)); $ss = serialize($s); unset($s,$o1,$o2); diff --git a/ext/spl/tests/SplObjectStorage/bug53071.phpt b/ext/spl/tests/SplObjectStorage/bug53071.phpt index e3bd5e1155b..0f0800d13ef 100644 --- a/ext/spl/tests/SplObjectStorage/bug53071.phpt +++ b/ext/spl/tests/SplObjectStorage/bug53071.phpt @@ -13,8 +13,8 @@ function LimitedScope() $myB = new SplObjectStorage(); $myC = new myClass(); $myC->member = $myA; // myC has a reference to myA - $myB->Attach($myC); // myB attaches myC - $myA->member = $myB; // myA has myB, comleting the cycle + $myB->offsetSet($myC); // myB attaches myC + $myA->member = $myB; // myA has myB, completing the cycle } LimitedScope(); var_dump(gc_collect_cycles()); diff --git a/ext/spl/tests/SplObjectStorage/bug67582.phpt b/ext/spl/tests/SplObjectStorage/bug67582.phpt index dc0cd532321..86a11e516ae 100644 --- a/ext/spl/tests/SplObjectStorage/bug67582.phpt +++ b/ext/spl/tests/SplObjectStorage/bug67582.phpt @@ -11,7 +11,7 @@ class MyObjectStorage extends SplObjectStorage { class TestObject {} $list = new MyObjectStorage(); -$list->attach(new TestObject()); +$list->offsetSet(new TestObject()); foreach($list as $x) var_dump($list->offsetExists($x)); diff --git a/ext/spl/tests/SplObjectStorage/bug69108.phpt b/ext/spl/tests/SplObjectStorage/bug69108.phpt index 3122da599c6..3579164791d 100644 --- a/ext/spl/tests/SplObjectStorage/bug69108.phpt +++ b/ext/spl/tests/SplObjectStorage/bug69108.phpt @@ -9,7 +9,7 @@ $b = new SplObjectStorage(); for ($i = 10000; $i > 0; $i--) { $object = new StdClass(); $a[] = $object; - $b->attach($object); + $b->offsetSet($object); } $c = serialize(array($a, $b)); diff --git a/ext/spl/tests/SplObjectStorage/bug69227.phpt b/ext/spl/tests/SplObjectStorage/bug69227.phpt index 812d8bafd8a..5a527d17df3 100644 --- a/ext/spl/tests/SplObjectStorage/bug69227.phpt +++ b/ext/spl/tests/SplObjectStorage/bug69227.phpt @@ -6,7 +6,7 @@ zend.enable_gc=1 attach($s); +$s->offsetSet($s); gc_collect_cycles(); echo "ok"; ?> diff --git a/ext/spl/tests/gh14639.phpt b/ext/spl/tests/SplObjectStorage/gh14639.phpt similarity index 94% rename from ext/spl/tests/gh14639.phpt rename to ext/spl/tests/SplObjectStorage/gh14639.phpt index 1b6f621d27b..41260855b25 100644 --- a/ext/spl/tests/gh14639.phpt +++ b/ext/spl/tests/SplObjectStorage/gh14639.phpt @@ -14,7 +14,7 @@ $b = new SplObjectStorage(); for ($i = 10000; $i > 0; $i--) { $object = new StdClass(); $object->a = str_repeat("a", 2); - $b->attach($object); + $b->offsetSet($object); } ?> --EXPECTF-- diff --git a/ext/spl/tests/observer_001.phpt b/ext/spl/tests/SplObjectStorage/observer_001.phpt similarity index 100% rename from ext/spl/tests/observer_001.phpt rename to ext/spl/tests/SplObjectStorage/observer_001.phpt diff --git a/ext/spl/tests/observer_002.phpt b/ext/spl/tests/SplObjectStorage/observer_002.phpt similarity index 96% rename from ext/spl/tests/observer_002.phpt rename to ext/spl/tests/SplObjectStorage/observer_002.phpt index 74bf3d4b930..227122b637d 100644 --- a/ext/spl/tests/observer_002.phpt +++ b/ext/spl/tests/SplObjectStorage/observer_002.phpt @@ -70,13 +70,13 @@ class SubjectImpl implements SplSubject function attach(SplObserver $observer): void { echo $this->name . '->' . __METHOD__ . '(' . $observer->getName() . ");\n"; - $this->observers->attach($observer); + $this->observers->offsetSet($observer); } function detach(SplObserver $observer): void { echo $this->name . '->' . __METHOD__ . '(' . $observer->getName() . ");\n"; - $this->observers->detach($observer); + $this->observers->offsetUnset($observer); } function count(): int @@ -100,7 +100,7 @@ class SubjectImpl implements SplSubject function contains($obj) { - return $this->observers->contains($obj); + return $this->observers->offsetExists($obj); } } diff --git a/ext/spl/tests/observer_003.phpt b/ext/spl/tests/SplObjectStorage/observer_003.phpt similarity index 93% rename from ext/spl/tests/observer_003.phpt rename to ext/spl/tests/SplObjectStorage/observer_003.phpt index 36ead923365..7708c526f94 100644 --- a/ext/spl/tests/observer_003.phpt +++ b/ext/spl/tests/SplObjectStorage/observer_003.phpt @@ -17,7 +17,7 @@ $storage = new SplObjectStorage(); foreach(array(1,"2","foo",true) as $value) { - $storage->attach(new TestClass($value)); + $storage->offsetSet(new TestClass($value)); } var_dump(count($storage)); diff --git a/ext/spl/tests/observer_004.phpt b/ext/spl/tests/SplObjectStorage/observer_004.phpt similarity index 97% rename from ext/spl/tests/observer_004.phpt rename to ext/spl/tests/SplObjectStorage/observer_004.phpt index b0b25ec117a..96d2e5b9999 100644 --- a/ext/spl/tests/observer_004.phpt +++ b/ext/spl/tests/SplObjectStorage/observer_004.phpt @@ -27,7 +27,7 @@ $storage = new MyStorage(); foreach(array(1,2) as $value) { - $storage->attach(new TestClass($value)); + $storage->offsetSet(new TestClass($value)); } var_dump(count($storage)); diff --git a/ext/spl/tests/observer_005.phpt b/ext/spl/tests/SplObjectStorage/observer_005.phpt similarity index 97% rename from ext/spl/tests/observer_005.phpt rename to ext/spl/tests/SplObjectStorage/observer_005.phpt index 833b978d725..b5b3669b870 100644 --- a/ext/spl/tests/observer_005.phpt +++ b/ext/spl/tests/SplObjectStorage/observer_005.phpt @@ -45,7 +45,7 @@ $storage = new MyStorage(1,2,3); foreach(array(array(4,5,6),array(7,8,9)) as $value) { - $storage->attach(new TestClass($value[0], $value[1], $value[2])); + $storage->offsetSet(new TestClass($value[0], $value[1], $value[2])); } var_dump(count($storage)); diff --git a/ext/spl/tests/observer_006.phpt b/ext/spl/tests/SplObjectStorage/observer_006.phpt similarity index 95% rename from ext/spl/tests/observer_006.phpt rename to ext/spl/tests/SplObjectStorage/observer_006.phpt index d1e53522797..afd40e9b122 100644 --- a/ext/spl/tests/observer_006.phpt +++ b/ext/spl/tests/SplObjectStorage/observer_006.phpt @@ -27,7 +27,7 @@ $storage = new MyStorage(); foreach(array(1=>"foo",2=>42) as $key => $value) { - $storage->attach(new TestClass($key), $value); + $storage->offsetSet(new TestClass($key), $value); } var_dump(count($storage)); @@ -52,8 +52,8 @@ foreach($storage2 as $object) } var_dump($storage2); -$storage->attach(new TestClass(3), new stdClass); -$storage->attach(new TestClass(4), new TestClass(5)); +$storage->offsetSet(new TestClass(3), new stdClass); +$storage->offsetSet(new TestClass(4), new TestClass(5)); echo "===UNSERIALIZE2===\n"; var_dump(unserialize(serialize($storage))); $storage->rewind(); @@ -70,7 +70,7 @@ $storage->next(); $storage->next(); var_dump($storage->key()); var_dump($storage->current()); -$storage->attach($storage->current(), "replaced"); +$storage->offsetSet($storage->current(), "replaced"); echo "===UNSERIALIZE4===\n"; var_dump(unserialize(serialize($storage))); diff --git a/ext/spl/tests/observer_007.phpt b/ext/spl/tests/SplObjectStorage/observer_007.phpt similarity index 100% rename from ext/spl/tests/observer_007.phpt rename to ext/spl/tests/SplObjectStorage/observer_007.phpt diff --git a/ext/spl/tests/observer_008.phpt b/ext/spl/tests/SplObjectStorage/observer_008.phpt similarity index 71% rename from ext/spl/tests/observer_008.phpt rename to ext/spl/tests/SplObjectStorage/observer_008.phpt index 0f6f0d263b9..36769c57d52 100644 --- a/ext/spl/tests/observer_008.phpt +++ b/ext/spl/tests/SplObjectStorage/observer_008.phpt @@ -9,24 +9,24 @@ $o2 = new StdClass; $o3 = new StdClass; $a = new A; -$a->attach($o1); -$a->attach($o2); +$a->offsetSet($o1); +$a->offsetSet($o2); $b = new SplObjectStorage(); -$b->attach($o2); -$b->attach($o3); +$b->offsetSet($o2); +$b->offsetSet($o3); -$a->addAll($b); +$a->offsetUnset($b); var_dump($a->count()); -$a->detach($o3); +$a->offsetUnset($o3); var_dump($a->count()); $a->removeAll($b); var_dump($a->count()); ?> --EXPECT-- -int(3) +int(2) int(2) int(1) diff --git a/ext/spl/tests/observer_009.phpt b/ext/spl/tests/SplObjectStorage/observer_009.phpt similarity index 87% rename from ext/spl/tests/observer_009.phpt rename to ext/spl/tests/SplObjectStorage/observer_009.phpt index 58f49980846..0b402c1d31e 100644 --- a/ext/spl/tests/observer_009.phpt +++ b/ext/spl/tests/SplObjectStorage/observer_009.phpt @@ -5,8 +5,8 @@ SPL: SplObjectStorage addAll/removeAll class Foo {} $storageA = new \SplObjectStorage(); -$storageA->attach(new \Foo); -$storageA->attach(new \Foo); +$storageA->offsetSet(new \Foo); +$storageA->offsetSet(new \Foo); echo ("Count storage A: " . count($storageA)); foreach ($storageA as $object) { diff --git a/ext/spl/tests/observer_010.phpt b/ext/spl/tests/SplObjectStorage/observer_010.phpt similarity index 100% rename from ext/spl/tests/observer_010.phpt rename to ext/spl/tests/SplObjectStorage/observer_010.phpt diff --git a/ext/spl/tests/arrayObject_getFlags_basic1.phpt b/ext/spl/tests/arrayObject_getFlags_basic1.phpt deleted file mode 100644 index 612a753680a..00000000000 --- a/ext/spl/tests/arrayObject_getFlags_basic1.phpt +++ /dev/null @@ -1,25 +0,0 @@ ---TEST-- -SPL: ArrayObject::getFlags() basic usage ---FILE-- -getFlags()); - -$ao = new ArrayObject(new ArrayObject(array(1,2,3)), ArrayObject::STD_PROP_LIST); -var_dump($ao->getFlags()); - -$ao = new ArrayObject(new ArrayIterator(new ArrayObject()), ArrayObject::ARRAY_AS_PROPS); -var_dump($ao->getFlags()); - -$ao = new ArrayObject(new ArrayObject(), ArrayObject::STD_PROP_LIST|ArrayObject::ARRAY_AS_PROPS); -var_dump($ao->getFlags()); - -$cao = clone $ao; -var_dump($cao->getFlags()); -?> ---EXPECT-- -int(0) -int(1) -int(2) -int(3) -int(3) diff --git a/ext/spl/tests/arrayObject_getFlags_basic2.phpt b/ext/spl/tests/arrayObject_getFlags_basic2.phpt deleted file mode 100644 index db44322d674..00000000000 --- a/ext/spl/tests/arrayObject_getFlags_basic2.phpt +++ /dev/null @@ -1,24 +0,0 @@ ---TEST-- -SPL: ArrayObject::getFlags() - ensure flags are passed on to nested array objects and iterators. ---FILE-- -getFlags()); - -$ao2 = new ArrayObject($ao); -var_dump($ao2->getFlags()); -var_dump($ao2->getIterator()->getFlags()); - -$ai = new ArrayIterator($ao); -var_dump($ai->getFlags()); - -$ao2 = new ArrayObject($ao, 0); -var_dump($ao2->getFlags()); - -?> ---EXPECT-- -int(3) -int(3) -int(3) -int(3) -int(0) diff --git a/ext/spl/tests/bug69845.phpt b/ext/spl/tests/bug69845.phpt deleted file mode 100644 index 09c9f2356d4..00000000000 --- a/ext/spl/tests/bug69845.phpt +++ /dev/null @@ -1,13 +0,0 @@ ---TEST-- -Fixed bug #69845 (ArrayObject with ARRAY_AS_PROPS broken) ---FILE-- -itemType = 'bulletin'; - var_dump(!is_null($data['itemType'])); -} -?> ---EXPECT-- -bool(true) -bool(true) diff --git a/ext/spl/tests/bug71204.phpt b/ext/spl/tests/bug71204.phpt index 8d1c721c100..3669597a084 100644 --- a/ext/spl/tests/bug71204.phpt +++ b/ext/spl/tests/bug71204.phpt @@ -13,6 +13,8 @@ spl_autoload_register(function ($name) { new A(); ?> --EXPECTF-- +Deprecated: spl_autoload_unregister(): Using spl_autoload_call() as a callback for spl_autoload_unregister() is deprecated, to remove all registered autoloaders, call spl_autoload_unregister() for all values returned from spl_autoload_functions() in %s on line %d + Fatal error: Uncaught Error: Class "A" not found in %s:%d Stack trace: #0 {main} diff --git a/ext/spl/tests/iterator_016.phpt b/ext/spl/tests/iterator_016.phpt index abc81c165ae..33ee7806420 100644 --- a/ext/spl/tests/iterator_016.phpt +++ b/ext/spl/tests/iterator_016.phpt @@ -8,7 +8,7 @@ class Menu extends ArrayObject function getIterator(): RecursiveArrayIterator { echo __METHOD__ . "\n"; - return new RecursiveArrayIterator($this); + return new RecursiveArrayIterator($this->getArrayCopy()); } } @@ -42,7 +42,18 @@ class MenuOutput extends RecursiveIteratorIterator } } -$arr = array("a", array("ba", array("bba", "bbb"), array(array("bcaa"))), array("ca"), "d"); +$arr = [ + "a", + [ + "ba", + ["bba", "bbb"], + [ + ["bcaa"] + ] + ], + ["ca"], + "d", +]; $obj = new Menu($arr); $rit = new MenuOutput($obj); foreach($rit as $k=>$v) diff --git a/ext/spl/tests/iterator_069.phpt b/ext/spl/tests/iterator_069.phpt index b9ee3f4b820..e30251fa916 100644 --- a/ext/spl/tests/iterator_069.phpt +++ b/ext/spl/tests/iterator_069.phpt @@ -3,10 +3,10 @@ SPL: RecursiveIteratorIterator cannot be used with foreach by reference --FILE-- getIterator()); +$recArrIt = new RecursiveArrayIterator([ + [1, 2], + ['a', 'b'], +]); $recItIt = new RecursiveIteratorIterator($recArrIt); diff --git a/ext/spl/tests/iterator_071.phpt b/ext/spl/tests/iterator_071.phpt index 7f525eb2c61..4f9b18d0c07 100644 --- a/ext/spl/tests/iterator_071.phpt +++ b/ext/spl/tests/iterator_071.phpt @@ -3,10 +3,10 @@ SPL: RecursiveIteratorIterator - Test where the case is RS_SELF and mode is CHIL --FILE-- getIterator()); +$recArrIt = new RecursiveArrayIterator([ + [1, 2], + ['a', 'b'], +]); class MyRecursiveIteratorIterator extends RecursiveIteratorIterator { @@ -29,4 +29,8 @@ MyRecursiveIteratorIterator::nextelement MyRecursiveIteratorIterator::nextelement 0 MyRecursiveIteratorIterator::nextelement +0 +MyRecursiveIteratorIterator::nextelement +1 +MyRecursiveIteratorIterator::nextelement 1 diff --git a/ext/spl/tests/recursiveIteratorIterator_beginchildren_error.phpt b/ext/spl/tests/recursiveIteratorIterator_beginchildren_error.phpt index 6a7d3eb8a51..76bacc3615f 100644 --- a/ext/spl/tests/recursiveIteratorIterator_beginchildren_error.phpt +++ b/ext/spl/tests/recursiveIteratorIterator_beginchildren_error.phpt @@ -3,10 +3,10 @@ SPL: RecursiveIteratorIterator - Exception thrown in beginchildren which should --FILE-- getIterator()); +$recArrIt = new RecursiveArrayIterator([ + [1, 2], + ['a', 'b'], +]); class MyRecursiveIteratorIterator extends RecursiveIteratorIterator { diff --git a/ext/spl/tests/recursiveIteratorIterator_callHasChildren_error.phpt b/ext/spl/tests/recursiveIteratorIterator_callHasChildren_error.phpt index 1c96ee9fcd0..9256e9e3b1b 100644 --- a/ext/spl/tests/recursiveIteratorIterator_callHasChildren_error.phpt +++ b/ext/spl/tests/recursiveIteratorIterator_callHasChildren_error.phpt @@ -3,10 +3,10 @@ SPL: RecursiveIteratorIterator - Exception thrown in callHasChildren which shoul --FILE-- getIterator()); +$recArrIt = new RecursiveArrayIterator([ + [1, 2], + ['a', 'b'], +]); class MyRecursiveIteratorIterator extends RecursiveIteratorIterator { diff --git a/ext/spl/tests/recursiveIteratorIterator_endchildren_error.phpt b/ext/spl/tests/recursiveIteratorIterator_endchildren_error.phpt index 13af7ce0198..07dee9c4acb 100644 --- a/ext/spl/tests/recursiveIteratorIterator_endchildren_error.phpt +++ b/ext/spl/tests/recursiveIteratorIterator_endchildren_error.phpt @@ -3,10 +3,10 @@ SPL: RecursiveIteratorIterator - Exception thrown in endchildren which should be --FILE-- getIterator()); +$recArrIt = new RecursiveArrayIterator([ + [1, 2], + ['a', 'b'], +]); class MyRecursiveIteratorIterator extends RecursiveIteratorIterator { @@ -30,6 +30,8 @@ foreach ($recItIt2 as $val) echo "$val\n"; --EXPECTF-- 1 2 +a +b ===NEXT LOOP=== 1 2 diff --git a/ext/spl/tests/recursiveIteratorIterator_nextelement_error.phpt b/ext/spl/tests/recursiveIteratorIterator_nextelement_error.phpt index d92d309c754..f89f47e849b 100644 --- a/ext/spl/tests/recursiveIteratorIterator_nextelement_error.phpt +++ b/ext/spl/tests/recursiveIteratorIterator_nextelement_error.phpt @@ -3,10 +3,10 @@ SPL: RecursiveIteratorIterator - Exception thrown in nextelement which should be --FILE-- getIterator()); +$recArrIt = new RecursiveArrayIterator([ + [1, 2], + ['a', 'b'], +]); class MyRecursiveIteratorIterator extends RecursiveIteratorIterator { diff --git a/ext/spl/tests/recursive_tree_iterator_005.phpt b/ext/spl/tests/recursive_tree_iterator_005.phpt deleted file mode 100644 index a63b26685c5..00000000000 --- a/ext/spl/tests/recursive_tree_iterator_005.phpt +++ /dev/null @@ -1,114 +0,0 @@ ---TEST-- -SPL: RecursiveTreeIterator and binary vs unicode (PHP 6.0+) ---INI-- -error_reporting=E_ALL&~E_NOTICE ---FILE-- - array( - (binary) "binary", - "abc2", - 1, - ), - (binary) "binary" => array( - 2, - "b", - 3 => array( - 4, - "c", - ), - "4abc" => array( - 4, - "c", - ), - ), -); - -$it = new RecursiveTreeIterator(new RecursiveArrayIterator($ary), 0); -foreach($it as $k => $v) { - var_dump($v); -} -echo "\n----------------\n\n"; -foreach($it as $k => $v) { - var_dump($k); -} -echo "\n----------------\n\n"; -echo "key, getEntry, current:\n"; -foreach($it as $k => $v) { - var_dump($it->key(), $it->getEntry(), $it->current()); -} -?> ---EXPECT-- -string(7) "|-Array" -string(10) "| |-binary" -string(8) "| |-abc2" -string(5) "| \-1" -string(7) "\-Array" -string(5) " |-2" -string(5) " |-b" -string(9) " |-Array" -string(7) " | |-4" -string(7) " | \-c" -string(9) " \-Array" -string(7) " |-4" -string(7) " \-c" - ----------------- - -string(3) "|-0" -string(5) "| |-0" -string(5) "| |-1" -string(5) "| \-2" -string(8) "\-binary" -string(5) " |-0" -string(5) " |-1" -string(5) " |-3" -string(7) " | |-0" -string(7) " | \-1" -string(8) " \-4abc" -string(7) " |-0" -string(7) " \-1" - ----------------- - -key, getEntry, current: -string(3) "|-0" -string(5) "Array" -string(7) "|-Array" -string(5) "| |-0" -string(6) "binary" -string(10) "| |-binary" -string(5) "| |-1" -string(4) "abc2" -string(8) "| |-abc2" -string(5) "| \-2" -string(1) "1" -string(5) "| \-1" -string(8) "\-binary" -string(5) "Array" -string(7) "\-Array" -string(5) " |-0" -string(1) "2" -string(5) " |-2" -string(5) " |-1" -string(1) "b" -string(5) " |-b" -string(5) " |-3" -string(5) "Array" -string(9) " |-Array" -string(7) " | |-0" -string(1) "4" -string(7) " | |-4" -string(7) " | \-1" -string(1) "c" -string(7) " | \-c" -string(8) " \-4abc" -string(5) "Array" -string(9) " \-Array" -string(7) " |-0" -string(1) "4" -string(7) " |-4" -string(7) " \-1" -string(1) "c" -string(7) " \-c" diff --git a/ext/spl/tests/recursive_tree_iterator_007.phpt b/ext/spl/tests/recursive_tree_iterator_007.phpt index 2907f39f265..75f1e6386c8 100644 --- a/ext/spl/tests/recursive_tree_iterator_007.phpt +++ b/ext/spl/tests/recursive_tree_iterator_007.phpt @@ -1,15 +1,16 @@ --TEST-- SPL: RecursiveTreeIterator and Exception from getEntry() ---INI-- -error_reporting=E_ALL&~E_NOTICE --FILE-- it = new RecursiveArrayIterator($it); } function getIterator(): Traversable { @@ -27,5 +28,10 @@ try { } ?> ---EXPECT-- +--EXPECTF-- +[0] => |-Array +[0] => | \-string +[1] => \-Array + +Deprecated: ArrayIterator::__construct(): Using an object as a backing array for ArrayIterator is deprecated, as it allows violating class constraints and invariants in %s on line %d Object of class stdClass could not be converted to string diff --git a/ext/spl/tests/spl_autoload_002.phpt b/ext/spl/tests/spl_autoload_002.phpt index 1a67baabd0b..2739e56e3be 100644 --- a/ext/spl/tests/spl_autoload_002.phpt +++ b/ext/spl/tests/spl_autoload_002.phpt @@ -35,7 +35,7 @@ spl_autoload_unregister('spl_autoload'); var_dump(spl_autoload_functions()); ?> ---EXPECT-- +--EXPECTF-- array(0) { } array(1) { @@ -56,6 +56,8 @@ array(2) { [1]=> string(16) "SplAutoloadTest2" } + +Deprecated: spl_autoload_unregister(): Using spl_autoload_call() as a callback for spl_autoload_unregister() is deprecated, to remove all registered autoloaders, call spl_autoload_unregister() for all values returned from spl_autoload_functions() in %s on line %d array(0) { } array(1) { diff --git a/ext/spl/tests/spl_autoload_unregister_without_registrations.phpt b/ext/spl/tests/spl_autoload_unregister_without_registrations.phpt index 0a7ca5a1352..867a67e6eb5 100644 --- a/ext/spl/tests/spl_autoload_unregister_without_registrations.phpt +++ b/ext/spl/tests/spl_autoload_unregister_without_registrations.phpt @@ -5,6 +5,8 @@ spl_autoload_unregister("spl_autoload_call") without registrations var_dump(spl_autoload_unregister("spl_autoload_call")); ?> Done ---EXPECT-- +--EXPECTF-- + +Deprecated: spl_autoload_unregister(): Using spl_autoload_call() as a callback for spl_autoload_unregister() is deprecated, to remove all registered autoloaders, call spl_autoload_unregister() for all values returned from spl_autoload_functions() in %s on line %d bool(true) Done diff --git a/ext/standard/array.c b/ext/standard/array.c index 522e7f715ac..981bda9a222 100644 --- a/ext/standard/array.c +++ b/ext/standard/array.c @@ -3318,6 +3318,9 @@ static void php_splice(HashTable *in_hash, zend_long offset, zend_long length, H zval *entry; /* Hash entry */ uint32_t iter_pos = zend_hash_iterators_lower_pos(in_hash, 0); + GC_ADDREF(in_hash); + HT_ALLOW_COW_VIOLATION(in_hash); /* Will be reset when setting the flags for in_hash */ + /* Get number of entries in the input hash */ num_in = zend_hash_num_elements(in_hash); @@ -3485,6 +3488,15 @@ static void php_splice(HashTable *in_hash, zend_long offset, zend_long length, H HT_SET_ITERATORS_COUNT(&out_hash, HT_ITERATORS_COUNT(in_hash)); HT_SET_ITERATORS_COUNT(in_hash, 0); in_hash->pDestructor = NULL; + + if (UNEXPECTED(GC_DELREF(in_hash) == 0)) { + /* Array was completely deallocated during the operation */ + zend_array_destroy(in_hash); + zend_hash_destroy(&out_hash); + zend_throw_error(NULL, "Array was modified during array_splice operation"); + return; + } + zend_hash_destroy(in_hash); HT_FLAGS(in_hash) = HT_FLAGS(&out_hash); @@ -6051,7 +6063,7 @@ PHP_FUNCTION(array_multisort) for (i = 0; i < MULTISORT_LAST; i++) { parse_state[i] = 0; } - func = ARRAYG(multisort_func) = ecalloc(argc, sizeof(bucket_compare_func_t)); + func = ecalloc(argc, sizeof(bucket_compare_func_t)); /* Here we go through the input arguments and parse them. Each one can * be either an array or a sort flag which follows an array. If not @@ -6067,7 +6079,7 @@ PHP_FUNCTION(array_multisort) /* We see the next array, so we update the sort flags of * the previous array and reset the sort flags. */ if (i > 0) { - ARRAYG(multisort_func)[num_arrays - 1] = php_get_data_compare_func_unstable(sort_type, sort_order != PHP_SORT_ASC); + func[num_arrays - 1] = php_get_data_compare_func_unstable(sort_type, sort_order != PHP_SORT_ASC); sort_order = PHP_SORT_ASC; sort_type = PHP_SORT_REGULAR; } @@ -6119,8 +6131,6 @@ PHP_FUNCTION(array_multisort) MULTISORT_ABORT; } } - /* Take care of the last array sort flags. */ - ARRAYG(multisort_func)[num_arrays - 1] = php_get_data_compare_func_unstable(sort_type, sort_order != PHP_SORT_ASC); /* Make sure the arrays are of the same size. */ array_size = zend_hash_num_elements(Z_ARRVAL_P(arrays[0])); @@ -6138,6 +6148,11 @@ PHP_FUNCTION(array_multisort) RETURN_TRUE; } + /* Take care of the last array sort flags. */ + func[num_arrays - 1] = php_get_data_compare_func_unstable(sort_type, sort_order != PHP_SORT_ASC); + bucket_compare_func_t *old_multisort_func = ARRAYG(multisort_func); + ARRAYG(multisort_func) = func; + /* Create the indirection array. This array is of size MxN, where * M is the number of entries in each input array and N is the number * of the input arrays + 1. The last column is UNDEF to indicate the end @@ -6214,6 +6229,7 @@ clean_up: efree(indirect); efree(func); efree(arrays); + ARRAYG(multisort_func) = old_multisort_func; } /* }}} */ @@ -7023,6 +7039,7 @@ PHP_FUNCTION(array_chunk) } array_init_size(return_value, (uint32_t)(((num_in - 1) / size) + 1)); + zend_hash_real_init_packed(Z_ARRVAL_P(return_value)); ZVAL_UNDEF(&chunk); @@ -7046,9 +7063,10 @@ PHP_FUNCTION(array_chunk) /* If reached the chunk size, add it to the result array, and reset the * pointer. */ - if (!(++current % size)) { + if (++current == size) { add_next_index_zval(return_value, &chunk); ZVAL_UNDEF(&chunk); + current = 0; } } ZEND_HASH_FOREACH_END(); diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c index ea2f8884bde..24f7f926720 100644 --- a/ext/standard/basic_functions.c +++ b/ext/standard/basic_functions.c @@ -303,6 +303,7 @@ PHP_MINIT_FUNCTION(basic) /* {{{ */ BASIC_MINIT_SUBMODULE(standard_filters) BASIC_MINIT_SUBMODULE(user_filters) BASIC_MINIT_SUBMODULE(password) + BASIC_MINIT_SUBMODULE(image) #ifdef ZTS BASIC_MINIT_SUBMODULE(localeconv) @@ -376,6 +377,7 @@ PHP_MSHUTDOWN_FUNCTION(basic) /* {{{ */ #endif BASIC_MSHUTDOWN_SUBMODULE(crypt) BASIC_MSHUTDOWN_SUBMODULE(password) + BASIC_MSHUTDOWN_SUBMODULE(image) return SUCCESS; } diff --git a/ext/standard/basic_functions.stub.php b/ext/standard/basic_functions.stub.php index b7be370bb47..541415a5ab9 100644 --- a/ext/standard/basic_functions.stub.php +++ b/ext/standard/basic_functions.stub.php @@ -646,6 +646,11 @@ const IMAGETYPE_WEBP = UNKNOWN; * @cvalue IMAGE_FILETYPE_AVIF */ const IMAGETYPE_AVIF = UNKNOWN; +/** + * @var int + * @cvalue IMAGE_FILETYPE_HEIF + */ +const IMAGETYPE_HEIF = UNKNOWN; /** * @var int * @cvalue IMAGE_FILETYPE_UNKNOWN @@ -653,7 +658,7 @@ const IMAGETYPE_AVIF = UNKNOWN; const IMAGETYPE_UNKNOWN = UNKNOWN; /** * @var int - * @cvalue IMAGE_FILETYPE_COUNT + * @cvalue IMAGE_FILETYPE_FIXED_COUNT */ const IMAGETYPE_COUNT = UNKNOWN; @@ -3582,6 +3587,7 @@ function stream_set_timeout($stream, int $seconds, int $microseconds = 0): bool * @param resource $stream * @alias stream_set_timeout */ +#[\Deprecated(since: '8.5', message: "use stream_set_timeout() instead")] function socket_set_timeout($stream, int $seconds, int $microseconds = 0): bool {} #endif diff --git a/ext/standard/basic_functions_arginfo.h b/ext/standard/basic_functions_arginfo.h index c77447bd83c..ba9d1710137 100644 --- a/ext/standard/basic_functions_arginfo.h +++ b/ext/standard/basic_functions_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: b9958c8f2f643e072ba7c6ee33ad238ea8dd702e */ + * Stub hash: deb4ea96dd130d8a0174678095c30a61e118bd60 */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_set_time_limit, 0, 1, _IS_BOOL, 0) ZEND_ARG_TYPE_INFO(0, seconds, IS_LONG, 0) @@ -3431,7 +3431,7 @@ static const zend_function_entry ext_functions[] = { ZEND_FE(stream_set_chunk_size, arginfo_stream_set_chunk_size) #if (defined(HAVE_SYS_TIME_H) || defined(PHP_WIN32)) ZEND_FE(stream_set_timeout, arginfo_stream_set_timeout) - ZEND_RAW_FENTRY("socket_set_timeout", zif_stream_set_timeout, arginfo_socket_set_timeout, 0, NULL, NULL) + ZEND_RAW_FENTRY("socket_set_timeout", zif_stream_set_timeout, arginfo_socket_set_timeout, ZEND_ACC_DEPRECATED, NULL, NULL) #endif ZEND_RAW_FENTRY("gettype", zif_gettype, arginfo_gettype, ZEND_ACC_COMPILE_TIME_EVAL, NULL, NULL) ZEND_RAW_FENTRY("get_debug_type", zif_get_debug_type, arginfo_get_debug_type, ZEND_ACC_COMPILE_TIME_EVAL, NULL, NULL) @@ -3645,8 +3645,9 @@ static void register_basic_functions_symbols(int module_number) REGISTER_LONG_CONSTANT("IMAGETYPE_ICO", IMAGE_FILETYPE_ICO, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("IMAGETYPE_WEBP", IMAGE_FILETYPE_WEBP, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("IMAGETYPE_AVIF", IMAGE_FILETYPE_AVIF, CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("IMAGETYPE_HEIF", IMAGE_FILETYPE_HEIF, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("IMAGETYPE_UNKNOWN", IMAGE_FILETYPE_UNKNOWN, CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("IMAGETYPE_COUNT", IMAGE_FILETYPE_COUNT, CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("IMAGETYPE_COUNT", IMAGE_FILETYPE_FIXED_COUNT, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("INFO_GENERAL", PHP_INFO_GENERAL, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("INFO_CREDITS", PHP_INFO_CREDITS, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("INFO_CONFIGURATION", PHP_INFO_CONFIGURATION, CONST_PERSISTENT); @@ -3896,10 +3897,8 @@ static void register_basic_functions_symbols(int module_number) zend_attribute *attribute_Deprecated_func_strptime_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "strptime", sizeof("strptime") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_func_strptime_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_2)); attribute_Deprecated_func_strptime_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_strptime_0_arg1; zend_string *attribute_Deprecated_func_strptime_0_arg1_str = zend_string_init("use date_parse_from_format() (for locale-independent parsing), or IntlDateFormatter::parse() (for locale-dependent parsing) instead", strlen("use date_parse_from_format() (for locale-independent parsing), or IntlDateFormatter::parse() (for locale-dependent parsing) instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_strptime_0_arg1, attribute_Deprecated_func_strptime_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_strptime_0->args[1].value, &attribute_Deprecated_func_strptime_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_strptime_0->args[1].value, attribute_Deprecated_func_strptime_0_arg1_str); attribute_Deprecated_func_strptime_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); #endif @@ -3910,68 +3909,58 @@ static void register_basic_functions_symbols(int module_number) zend_attribute *attribute_Deprecated_func_utf8_encode_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "utf8_encode", sizeof("utf8_encode") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_func_utf8_encode_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_2)); attribute_Deprecated_func_utf8_encode_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_utf8_encode_0_arg1; zend_string *attribute_Deprecated_func_utf8_encode_0_arg1_str = zend_string_init("visit the php.net documentation for various alternatives", strlen("visit the php.net documentation for various alternatives"), 1); - ZVAL_STR(&attribute_Deprecated_func_utf8_encode_0_arg1, attribute_Deprecated_func_utf8_encode_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_utf8_encode_0->args[1].value, &attribute_Deprecated_func_utf8_encode_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_utf8_encode_0->args[1].value, attribute_Deprecated_func_utf8_encode_0_arg1_str); attribute_Deprecated_func_utf8_encode_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_func_utf8_decode_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "utf8_decode", sizeof("utf8_decode") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_func_utf8_decode_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_2)); attribute_Deprecated_func_utf8_decode_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_utf8_decode_0_arg1; - zend_string *attribute_Deprecated_func_utf8_decode_0_arg1_str = zend_string_init("visit the php.net documentation for various alternatives", strlen("visit the php.net documentation for various alternatives"), 1); - ZVAL_STR(&attribute_Deprecated_func_utf8_decode_0_arg1, attribute_Deprecated_func_utf8_decode_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_utf8_decode_0->args[1].value, &attribute_Deprecated_func_utf8_decode_0_arg1); + ZVAL_STR_COPY(&attribute_Deprecated_func_utf8_decode_0->args[1].value, attribute_Deprecated_func_utf8_encode_0_arg1_str); attribute_Deprecated_func_utf8_decode_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_add_parameter_attribute(zend_hash_str_find_ptr(CG(function_table), "password_hash", sizeof("password_hash") - 1), 0, ZSTR_KNOWN(ZEND_STR_SENSITIVEPARAMETER), 0); zend_add_parameter_attribute(zend_hash_str_find_ptr(CG(function_table), "password_verify", sizeof("password_verify") - 1), 0, ZSTR_KNOWN(ZEND_STR_SENSITIVEPARAMETER), 0); +#if (defined(HAVE_SYS_TIME_H) || defined(PHP_WIN32)) + + zend_attribute *attribute_Deprecated_func_socket_set_timeout_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "socket_set_timeout", sizeof("socket_set_timeout") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + ZVAL_STR(&attribute_Deprecated_func_socket_set_timeout_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_5)); + attribute_Deprecated_func_socket_set_timeout_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zend_string *attribute_Deprecated_func_socket_set_timeout_0_arg1_str = zend_string_init("use stream_set_timeout() instead", strlen("use stream_set_timeout() instead"), 1); + ZVAL_STR(&attribute_Deprecated_func_socket_set_timeout_0->args[1].value, attribute_Deprecated_func_socket_set_timeout_0_arg1_str); + attribute_Deprecated_func_socket_set_timeout_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); +#endif zend_attribute *attribute_Deprecated_const_ASSERT_ACTIVE_0 = zend_add_global_constant_attribute(const_ASSERT_ACTIVE, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_const_ASSERT_ACTIVE_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_3)); attribute_Deprecated_const_ASSERT_ACTIVE_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_const_ASSERT_ACTIVE_0_arg1; zend_string *attribute_Deprecated_const_ASSERT_ACTIVE_0_arg1_str = zend_string_init("as assert_options() is deprecated", strlen("as assert_options() is deprecated"), 1); - ZVAL_STR(&attribute_Deprecated_const_ASSERT_ACTIVE_0_arg1, attribute_Deprecated_const_ASSERT_ACTIVE_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_const_ASSERT_ACTIVE_0->args[1].value, &attribute_Deprecated_const_ASSERT_ACTIVE_0_arg1); + ZVAL_STR(&attribute_Deprecated_const_ASSERT_ACTIVE_0->args[1].value, attribute_Deprecated_const_ASSERT_ACTIVE_0_arg1_str); attribute_Deprecated_const_ASSERT_ACTIVE_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_const_ASSERT_CALLBACK_0 = zend_add_global_constant_attribute(const_ASSERT_CALLBACK, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_const_ASSERT_CALLBACK_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_3)); attribute_Deprecated_const_ASSERT_CALLBACK_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_const_ASSERT_CALLBACK_0_arg1; - zend_string *attribute_Deprecated_const_ASSERT_CALLBACK_0_arg1_str = zend_string_init("as assert_options() is deprecated", strlen("as assert_options() is deprecated"), 1); - ZVAL_STR(&attribute_Deprecated_const_ASSERT_CALLBACK_0_arg1, attribute_Deprecated_const_ASSERT_CALLBACK_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_const_ASSERT_CALLBACK_0->args[1].value, &attribute_Deprecated_const_ASSERT_CALLBACK_0_arg1); + ZVAL_STR_COPY(&attribute_Deprecated_const_ASSERT_CALLBACK_0->args[1].value, attribute_Deprecated_const_ASSERT_ACTIVE_0_arg1_str); attribute_Deprecated_const_ASSERT_CALLBACK_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_const_ASSERT_BAIL_0 = zend_add_global_constant_attribute(const_ASSERT_BAIL, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_const_ASSERT_BAIL_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_3)); attribute_Deprecated_const_ASSERT_BAIL_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_const_ASSERT_BAIL_0_arg1; - zend_string *attribute_Deprecated_const_ASSERT_BAIL_0_arg1_str = zend_string_init("as assert_options() is deprecated", strlen("as assert_options() is deprecated"), 1); - ZVAL_STR(&attribute_Deprecated_const_ASSERT_BAIL_0_arg1, attribute_Deprecated_const_ASSERT_BAIL_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_const_ASSERT_BAIL_0->args[1].value, &attribute_Deprecated_const_ASSERT_BAIL_0_arg1); + ZVAL_STR_COPY(&attribute_Deprecated_const_ASSERT_BAIL_0->args[1].value, attribute_Deprecated_const_ASSERT_ACTIVE_0_arg1_str); attribute_Deprecated_const_ASSERT_BAIL_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_const_ASSERT_WARNING_0 = zend_add_global_constant_attribute(const_ASSERT_WARNING, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_const_ASSERT_WARNING_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_3)); attribute_Deprecated_const_ASSERT_WARNING_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_const_ASSERT_WARNING_0_arg1; - zend_string *attribute_Deprecated_const_ASSERT_WARNING_0_arg1_str = zend_string_init("as assert_options() is deprecated", strlen("as assert_options() is deprecated"), 1); - ZVAL_STR(&attribute_Deprecated_const_ASSERT_WARNING_0_arg1, attribute_Deprecated_const_ASSERT_WARNING_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_const_ASSERT_WARNING_0->args[1].value, &attribute_Deprecated_const_ASSERT_WARNING_0_arg1); + ZVAL_STR_COPY(&attribute_Deprecated_const_ASSERT_WARNING_0->args[1].value, attribute_Deprecated_const_ASSERT_ACTIVE_0_arg1_str); attribute_Deprecated_const_ASSERT_WARNING_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_const_ASSERT_EXCEPTION_0 = zend_add_global_constant_attribute(const_ASSERT_EXCEPTION, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_const_ASSERT_EXCEPTION_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_3)); attribute_Deprecated_const_ASSERT_EXCEPTION_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_const_ASSERT_EXCEPTION_0_arg1; - zend_string *attribute_Deprecated_const_ASSERT_EXCEPTION_0_arg1_str = zend_string_init("as assert_options() is deprecated", strlen("as assert_options() is deprecated"), 1); - ZVAL_STR(&attribute_Deprecated_const_ASSERT_EXCEPTION_0_arg1, attribute_Deprecated_const_ASSERT_EXCEPTION_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_const_ASSERT_EXCEPTION_0->args[1].value, &attribute_Deprecated_const_ASSERT_EXCEPTION_0_arg1); + ZVAL_STR_COPY(&attribute_Deprecated_const_ASSERT_EXCEPTION_0->args[1].value, attribute_Deprecated_const_ASSERT_ACTIVE_0_arg1_str); attribute_Deprecated_const_ASSERT_EXCEPTION_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); } diff --git a/ext/standard/dir.c b/ext/standard/dir.c index cced88e4ac8..2eb9d853eeb 100644 --- a/ext/standard/dir.c +++ b/ext/standard/dir.c @@ -160,6 +160,8 @@ PHP_FUNCTION(dir) static php_stream* php_dir_get_directory_stream_from_user_arg(php_stream *dir_stream) { if (dir_stream == NULL) { + php_error_docref(NULL, E_DEPRECATED, + "Passing null is deprecated, instead the last opened directory stream should be provided"); if (UNEXPECTED(DIRG(default_dir) == NULL)) { zend_type_error("No resource supplied"); return NULL; diff --git a/ext/standard/exec.c b/ext/standard/exec.c index ce3e8565ad2..762d8bee13c 100644 --- a/ext/standard/exec.c +++ b/ext/standard/exec.c @@ -199,13 +199,12 @@ err: static void php_exec_ex(INTERNAL_FUNCTION_PARAMETERS, int mode) /* {{{ */ { - char *cmd; - size_t cmd_len; + zend_string *cmd; zval *ret_code=NULL, *ret_array=NULL; int ret; ZEND_PARSE_PARAMETERS_START(1, (mode ? 2 : 3)) - Z_PARAM_STRING(cmd, cmd_len) + Z_PARAM_PATH_STR(cmd) Z_PARAM_OPTIONAL if (!mode) { Z_PARAM_ZVAL(ret_array) @@ -213,17 +212,13 @@ static void php_exec_ex(INTERNAL_FUNCTION_PARAMETERS, int mode) /* {{{ */ Z_PARAM_ZVAL(ret_code) ZEND_PARSE_PARAMETERS_END(); - if (!cmd_len) { + if (UNEXPECTED(!ZSTR_LEN(cmd))) { zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } - if (strlen(cmd) != cmd_len) { - zend_argument_value_error(1, "must not contain any null bytes"); - RETURN_THROWS(); - } if (!ret_array) { - ret = php_exec(mode, cmd, NULL, return_value); + ret = php_exec(mode, ZSTR_VAL(cmd), NULL, return_value); } else { if (Z_TYPE_P(Z_REFVAL_P(ret_array)) == IS_ARRAY) { ZVAL_DEREF(ret_array); @@ -235,7 +230,7 @@ static void php_exec_ex(INTERNAL_FUNCTION_PARAMETERS, int mode) /* {{{ */ } } - ret = php_exec(2, cmd, ret_array, return_value); + ret = php_exec(2, ZSTR_VAL(cmd), ret_array, return_value); } if (ret_code) { ZEND_TRY_ASSIGN_REF_LONG(ret_code, ret); @@ -280,7 +275,7 @@ PHPAPI zend_string *php_escape_shell_cmd(const zend_string *unescaped_cmd) char *p = NULL; #endif - ZEND_ASSERT(ZSTR_LEN(unescaped_cmd) == strlen(ZSTR_VAL(unescaped_cmd)) && "Must be a binary safe string"); + ZEND_ASSERT(!zend_str_has_nul_byte(unescaped_cmd) && "Must be a binary safe string"); size_t l = ZSTR_LEN(unescaped_cmd); const char *str = ZSTR_VAL(unescaped_cmd); @@ -387,7 +382,7 @@ PHPAPI zend_string *php_escape_shell_arg(const zend_string *unescaped_arg) size_t x, y = 0; zend_string *cmd; - ZEND_ASSERT(ZSTR_LEN(unescaped_arg) == strlen(ZSTR_VAL(unescaped_arg)) && "Must be a binary safe string"); + ZEND_ASSERT(!zend_str_has_nul_byte(unescaped_arg) && "Must be a binary safe string"); size_t l = ZSTR_LEN(unescaped_arg); const char *str = ZSTR_VAL(unescaped_arg); diff --git a/ext/standard/file_arginfo.h b/ext/standard/file_arginfo.h index 471c9a07cb4..ee9b2c4ff7d 100644 --- a/ext/standard/file_arginfo.h +++ b/ext/standard/file_arginfo.h @@ -123,18 +123,13 @@ static void register_file_symbols(int module_number) zend_attribute *attribute_Deprecated_const_FILE_TEXT_0 = zend_add_global_constant_attribute(const_FILE_TEXT, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_const_FILE_TEXT_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_1)); attribute_Deprecated_const_FILE_TEXT_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_const_FILE_TEXT_0_arg1; zend_string *attribute_Deprecated_const_FILE_TEXT_0_arg1_str = zend_string_init("as the constant has no effect", strlen("as the constant has no effect"), 1); - ZVAL_STR(&attribute_Deprecated_const_FILE_TEXT_0_arg1, attribute_Deprecated_const_FILE_TEXT_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_const_FILE_TEXT_0->args[1].value, &attribute_Deprecated_const_FILE_TEXT_0_arg1); + ZVAL_STR(&attribute_Deprecated_const_FILE_TEXT_0->args[1].value, attribute_Deprecated_const_FILE_TEXT_0_arg1_str); attribute_Deprecated_const_FILE_TEXT_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_const_FILE_BINARY_0 = zend_add_global_constant_attribute(const_FILE_BINARY, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_const_FILE_BINARY_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_1)); attribute_Deprecated_const_FILE_BINARY_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_const_FILE_BINARY_0_arg1; - zend_string *attribute_Deprecated_const_FILE_BINARY_0_arg1_str = zend_string_init("as the constant has no effect", strlen("as the constant has no effect"), 1); - ZVAL_STR(&attribute_Deprecated_const_FILE_BINARY_0_arg1, attribute_Deprecated_const_FILE_BINARY_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_const_FILE_BINARY_0->args[1].value, &attribute_Deprecated_const_FILE_BINARY_0_arg1); + ZVAL_STR_COPY(&attribute_Deprecated_const_FILE_BINARY_0->args[1].value, attribute_Deprecated_const_FILE_TEXT_0_arg1_str); attribute_Deprecated_const_FILE_BINARY_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); } diff --git a/ext/standard/filestat.c b/ext/standard/filestat.c index 7cb54aa0aca..85c2517ed91 100644 --- a/ext/standard/filestat.c +++ b/ext/standard/filestat.c @@ -749,7 +749,7 @@ PHPAPI void php_stat(zend_string *filename, int type, zval *return_value) php_stream_wrapper *wrapper = NULL; if (IS_ACCESS_CHECK(type)) { - if (!ZSTR_LEN(filename) || CHECK_NULL_PATH(ZSTR_VAL(filename), ZSTR_LEN(filename))) { + if (!ZSTR_LEN(filename) || zend_str_has_nul_byte(filename)) { if (ZSTR_LEN(filename) && !IS_EXISTS_CHECK(type)) { php_error_docref(NULL, E_WARNING, "Filename contains null byte"); } @@ -821,7 +821,7 @@ PHPAPI void php_stat(zend_string *filename, int type, zval *return_value) } if (!wrapper) { - if (!ZSTR_LEN(filename) || CHECK_NULL_PATH(ZSTR_VAL(filename), ZSTR_LEN(filename))) { + if (!ZSTR_LEN(filename) || zend_str_has_nul_byte(filename)) { if (ZSTR_LEN(filename) && !IS_EXISTS_CHECK(type)) { php_error_docref(NULL, E_WARNING, "Filename contains null byte"); } diff --git a/ext/standard/filters.c b/ext/standard/filters.c index 3dcbc4bc320..34393be54d8 100644 --- a/ext/standard/filters.c +++ b/ext/standard/filters.c @@ -1557,7 +1557,6 @@ static const php_stream_filter_ops strfilter_convert_ops = { static php_stream_filter *strfilter_convert_create(const char *filtername, zval *filterparams, uint8_t persistent) { php_convert_filter *inst; - php_stream_filter *retval = NULL; char *dot; int conv_mode = 0; @@ -1587,16 +1586,11 @@ static php_stream_filter *strfilter_convert_create(const char *filtername, zval if (php_convert_filter_ctor(inst, conv_mode, (filterparams != NULL ? Z_ARRVAL_P(filterparams) : NULL), filtername, persistent) != SUCCESS) { - goto out; - } - - retval = php_stream_filter_alloc(&strfilter_convert_ops, inst, persistent); -out: - if (retval == NULL) { pefree(inst, persistent); + return NULL; } - return retval; + return php_stream_filter_alloc(&strfilter_convert_ops, inst, persistent); } static const php_stream_filter_factory strfilter_convert_factory = { diff --git a/ext/standard/head.c b/ext/standard/head.c index ccef4be16bd..0b497fdc42a 100644 --- a/ext/standard/head.c +++ b/ext/standard/head.c @@ -79,7 +79,7 @@ PHPAPI bool php_header(void) #define ILLEGAL_COOKIE_CHARACTER "\",\", \";\", \" \", \"\\t\", \"\\r\", \"\\n\", \"\\013\", or \"\\014\"" PHPAPI zend_result php_setcookie(zend_string *name, zend_string *value, time_t expires, zend_string *path, zend_string *domain, bool secure, bool httponly, - zend_string *samesite, bool url_encode) + zend_string *samesite, bool partitioned, bool url_encode) { zend_string *dt; sapi_header_line ctr = {0}; @@ -117,6 +117,11 @@ PHPAPI zend_result php_setcookie(zend_string *name, zend_string *value, time_t e return FAILURE; } #endif + if (partitioned && !secure) { + zend_value_error("%s(): \"partitioned\" option cannot be used without \"secure\" option", + get_active_function_name()); + return FAILURE; + } /* Should check value of SameSite? */ @@ -182,6 +187,9 @@ PHPAPI zend_result php_setcookie(zend_string *name, zend_string *value, time_t e smart_str_appends(&buf, COOKIE_SAMESITE); smart_str_append(&buf, samesite); } + if (partitioned) { + smart_str_appends(&buf, COOKIE_PARTITIONED); + } ctr.line = ZSTR_VAL(buf.s); ctr.line_len = (uint32_t) ZSTR_LEN(buf.s); @@ -192,7 +200,7 @@ PHPAPI zend_result php_setcookie(zend_string *name, zend_string *value, time_t e } static zend_result php_head_parse_cookie_options_array(HashTable *options, zend_long *expires, zend_string **path, - zend_string **domain, bool *secure, bool *httponly, zend_string **samesite) + zend_string **domain, bool *secure, bool *httponly, zend_string **samesite, bool *partitioned) { zend_string *key; zval *value; @@ -214,6 +222,8 @@ static zend_result php_head_parse_cookie_options_array(HashTable *options, zend_ *httponly = zval_is_true(value); } else if (zend_string_equals_literal_ci(key, "samesite")) { *samesite = zval_get_string(value); + } else if (zend_string_equals_literal_ci(key, "partitioned")) { + *partitioned = zval_is_true(value); } else { zend_value_error("%s(): option \"%s\" is invalid", get_active_function_name(), ZSTR_VAL(key)); return FAILURE; @@ -227,7 +237,7 @@ static void php_setcookie_common(INTERNAL_FUNCTION_PARAMETERS, bool is_raw) HashTable *options = NULL; zend_long expires = 0; zend_string *name, *value = NULL, *path = NULL, *domain = NULL, *samesite = NULL; - bool secure = 0, httponly = 0; + bool secure = 0, httponly = 0, partitioned = false; ZEND_PARSE_PARAMETERS_START(1, 7) Z_PARAM_STR(name) @@ -248,13 +258,13 @@ static void php_setcookie_common(INTERNAL_FUNCTION_PARAMETERS, bool is_raw) } if (FAILURE == php_head_parse_cookie_options_array(options, &expires, &path, - &domain, &secure, &httponly, &samesite) + &domain, &secure, &httponly, &samesite, &partitioned) ) { goto cleanup; } } - if (php_setcookie(name, value, expires, path, domain, secure, httponly, samesite, !is_raw) == SUCCESS) { + if (php_setcookie(name, value, expires, path, domain, secure, httponly, samesite, partitioned, !is_raw) == SUCCESS) { RETVAL_TRUE; } else { RETVAL_FALSE; diff --git a/ext/standard/head.h b/ext/standard/head.h index 32c2570a532..0272fec2dc2 100644 --- a/ext/standard/head.h +++ b/ext/standard/head.h @@ -17,19 +17,20 @@ #ifndef HEAD_H #define HEAD_H -#define COOKIE_EXPIRES "; expires=" -#define COOKIE_MAX_AGE "; Max-Age=" -#define COOKIE_DOMAIN "; domain=" -#define COOKIE_PATH "; path=" -#define COOKIE_SECURE "; secure" -#define COOKIE_HTTPONLY "; HttpOnly" -#define COOKIE_SAMESITE "; SameSite=" +#define COOKIE_EXPIRES "; expires=" +#define COOKIE_MAX_AGE "; Max-Age=" +#define COOKIE_DOMAIN "; domain=" +#define COOKIE_PATH "; path=" +#define COOKIE_SECURE "; secure" +#define COOKIE_HTTPONLY "; HttpOnly" +#define COOKIE_SAMESITE "; SameSite=" +#define COOKIE_PARTITIONED "; Partitioned" extern PHP_RINIT_FUNCTION(head); PHPAPI bool php_header(void); PHPAPI zend_result php_setcookie(zend_string *name, zend_string *value, time_t expires, zend_string *path, zend_string *domain, bool secure, bool httponly, - zend_string *samesite, bool url_encode); + zend_string *samesite, bool partitioned, bool url_encode); #endif diff --git a/ext/standard/hrtime.c b/ext/standard/hrtime.c index f8d5e317913..10853493b63 100644 --- a/ext/standard/hrtime.c +++ b/ext/standard/hrtime.c @@ -46,7 +46,6 @@ delivered timestamp is monotonic and cannot be adjusted. */ PHP_FUNCTION(hrtime) { -#if ZEND_HRTIME_AVAILABLE bool get_as_num = 0; zend_hrtime_t t = zend_hrtime(); @@ -55,6 +54,7 @@ PHP_FUNCTION(hrtime) Z_PARAM_BOOL(get_as_num) ZEND_PARSE_PARAMETERS_END(); +#if ZEND_HRTIME_AVAILABLE if (UNEXPECTED(get_as_num)) { PHP_RETURN_HRTIME(t); } else { diff --git a/ext/standard/html.c b/ext/standard/html.c index 0c6231d590d..af6e6ec9444 100644 --- a/ext/standard/html.c +++ b/ext/standard/html.c @@ -809,112 +809,148 @@ static inline size_t write_octet_sequence(unsigned char *buf, enum entity_charse /* +2 is 1 because of rest (probably unnecessary), 1 because of terminating 0 */ #define TRAVERSE_FOR_ENTITIES_EXPAND_SIZE(oldlen) ((oldlen) + (oldlen) / 5 + 2) static void traverse_for_entities( - const char *old, - size_t oldlen, - zend_string *ret, /* should have allocated TRAVERSE_FOR_ENTITIES_EXPAND_SIZE(olden) */ - int all, - int flags, + const zend_string *input, + zend_string *output, /* should have allocated TRAVERSE_FOR_ENTITIES_EXPAND_SIZE(olden) */ + const int all, + const int flags, const entity_ht *inv_map, - enum entity_charset charset) + const enum entity_charset charset) { - const char *p, - *lim; - char *q; - int doctype = flags & ENT_HTML_DOC_TYPE_MASK; + const char *current_ptr = ZSTR_VAL(input); + const char *input_end = current_ptr + ZSTR_LEN(input); /* terminator address */ + char *output_ptr = ZSTR_VAL(output); + const int doctype = flags & ENT_HTML_DOC_TYPE_MASK; - lim = old + oldlen; /* terminator address */ - assert(*lim == '\0'); - - for (p = old, q = ZSTR_VAL(ret); p < lim;) { - unsigned code, code2 = 0; - const char *next = NULL; /* when set, next > p, otherwise possible inf loop */ - - /* Shift JIS, Big5 and HKSCS use multi-byte encodings where an - * ASCII range byte can be part of a multi-byte sequence. - * However, they start at 0x40, therefore if we find a 0x26 byte, - * we're sure it represents the '&' character. */ - - /* assumes there are no single-char entities */ - if (p[0] != '&' || (p + 3 >= lim)) { - *(q++) = *(p++); - continue; + while (current_ptr < input_end) { + const char *ampersand_ptr = memchr(current_ptr, '&', input_end - current_ptr); + if (!ampersand_ptr) { + const size_t tail_len = input_end - current_ptr; + if (tail_len > 0) { + memcpy(output_ptr, current_ptr, tail_len); + output_ptr += tail_len; + } + break; } - /* now p[3] is surely valid and is no terminator */ + /* Copy everything up to the found '&' */ + const size_t chunk_len = ampersand_ptr - current_ptr; + if (chunk_len > 0) { + memcpy(output_ptr, current_ptr, chunk_len); + output_ptr += chunk_len; + } - /* numerical entity */ - if (p[1] == '#') { - next = &p[2]; - if (process_numeric_entity(&next, &code) == FAILURE) - goto invalid_code; + /* Now current_ptr points to the '&' character. */ + current_ptr = ampersand_ptr; - /* If we're in htmlspecialchars_decode, we're only decoding entities - * that represent &, <, >, " and '. Is this one of them? */ - if (!all && (code > 63U || - stage3_table_be_apos_00000[code].data.ent.entity == NULL)) - goto invalid_code; + /* If there are less than 4 bytes remaining, there isn't enough for an entity - + * copy '&' as a normal character. */ + if (input_end - current_ptr < 4) { + const size_t remaining = input_end - current_ptr; + memcpy(output_ptr, current_ptr, remaining); + output_ptr += remaining; + break; + } - /* are we allowed to decode this entity in this document type? - * HTML 5 is the only that has a character that cannot be used in - * a numeric entity but is allowed literally (U+000D). The - * unoptimized version would be ... || !numeric_entity_is_allowed(code) */ - if (!unicode_cp_is_allowed(code, doctype) || - (doctype == ENT_HTML_DOC_HTML5 && code == 0x0D)) - goto invalid_code; + unsigned code = 0, code2 = 0; + const char *entity_end_ptr = NULL; + + if (current_ptr[1] == '#') { + /* Processing numeric entity */ + const char *num_start = current_ptr + 2; + entity_end_ptr = num_start; + if (process_numeric_entity(&entity_end_ptr, &code) == FAILURE) { + goto invalid_incomplete_entity; + } + if (!all && (code > 63U || stage3_table_be_apos_00000[code].data.ent.entity == NULL)) { + /* If we're in htmlspecialchars_decode, we're only decoding entities + * that represent &, <, >, " and '. Is this one of them? */ + goto invalid_incomplete_entity; + } else if (!unicode_cp_is_allowed(code, doctype) || + (doctype == ENT_HTML_DOC_HTML5 && code == 0x0D)) { + /* are we allowed to decode this entity in this document type? + * HTML 5 is the only that has a character that cannot be used in + * a numeric entity but is allowed literally (U+000D). The + * unoptimized version would be ... || !numeric_entity_is_allowed(code) */ + goto invalid_incomplete_entity; + } } else { - const char *start; - size_t ent_len; - - next = &p[1]; - start = next; - - if (process_named_entity_html(&next, &start, &ent_len) == FAILURE) - goto invalid_code; - - if (resolve_named_entity_html(start, ent_len, inv_map, &code, &code2) == FAILURE) { - if (doctype == ENT_HTML_DOC_XHTML && ent_len == 4 && start[0] == 'a' - && start[1] == 'p' && start[2] == 'o' && start[3] == 's') { - /* uses html4 inv_map, which doesn't include apos;. This is a - * hack to support it */ - code = (unsigned) '\''; + /* Processing named entity */ + const char *name_start = current_ptr + 1; + /* Search for ';' */ + const size_t max_search_len = MIN(LONGEST_ENTITY_LENGTH + 1, input_end - name_start); + const char *semi_colon_ptr = memchr(name_start, ';', max_search_len); + if (!semi_colon_ptr) { + goto invalid_incomplete_entity; + } else { + const size_t name_len = semi_colon_ptr - name_start; + if (name_len == 0) { + goto invalid_incomplete_entity; } else { - goto invalid_code; + if (resolve_named_entity_html(name_start, name_len, inv_map, &code, &code2) == FAILURE) { + if (doctype == ENT_HTML_DOC_XHTML && name_len == 4 && + name_start[0] == 'a' && name_start[1] == 'p' && + name_start[2] == 'o' && name_start[3] == 's') + { + /* uses html4 inv_map, which doesn't include apos;. This is a + * hack to support it */ + code = (unsigned)'\''; + } else { + goto invalid_incomplete_entity; + } + } + entity_end_ptr = semi_colon_ptr; } } } - assert(*next == ';'); + /* At this stage the entity_end_ptr should be always set. */ + ZEND_ASSERT(entity_end_ptr != NULL); - if (((code == '\'' && !(flags & ENT_HTML_QUOTE_SINGLE)) || - (code == '"' && !(flags & ENT_HTML_QUOTE_DOUBLE))) - /* && code2 == '\0' always true for current maps */) - goto invalid_code; + /* Check if quotes are allowed for entities representing ' or " */ + if ((code == '\'' && !(flags & ENT_HTML_QUOTE_SINGLE)) || + (code == '"' && !(flags & ENT_HTML_QUOTE_DOUBLE))) + { + goto invalid_complete_entity; + } /* UTF-8 doesn't need mapping (ISO-8859-1 doesn't either, but * the call is needed to ensure the codepoint <= U+00FF) */ if (charset != cs_utf_8) { /* replace unicode code point */ - if (map_from_unicode(code, charset, &code) == FAILURE || code2 != 0) - goto invalid_code; /* not representable in target charset */ + if (map_from_unicode(code, charset, &code) == FAILURE || code2 != 0) { + goto invalid_complete_entity; + } } - q += write_octet_sequence((unsigned char*)q, charset, code); + /* Write the parsed entity into the output buffer */ + output_ptr += write_octet_sequence((unsigned char*)output_ptr, charset, code); if (code2) { - q += write_octet_sequence((unsigned char*)q, charset, code2); + output_ptr += write_octet_sequence((unsigned char*)output_ptr, charset, code2); } - - /* jump over the valid entity; may go beyond size of buffer; np */ - p = next + 1; + /* Move current_ptr past the semicolon */ + current_ptr = entity_end_ptr + 1; continue; -invalid_code: - for (; p < next; p++) { - *(q++) = *p; +invalid_incomplete_entity: + /* If the entity is invalid at parse stage or entity_end_ptr was never found, copy '&' as normal */ + *output_ptr++ = *current_ptr++; + continue; + +invalid_complete_entity: + /* If the entity became invalid after we found entity_end_ptr */ + if (entity_end_ptr) { + const size_t len = entity_end_ptr - current_ptr; + memcpy(output_ptr, current_ptr, len); + output_ptr += len; + current_ptr = entity_end_ptr; + } else { + *output_ptr++ = *current_ptr++; } + continue; } - *q = '\0'; - ZSTR_LEN(ret) = (size_t)(q - ZSTR_VAL(ret)); + *output_ptr = '\0'; + ZSTR_LEN(output) = (size_t)(output_ptr - ZSTR_VAL(output)); } /* }}} */ @@ -999,7 +1035,7 @@ PHPAPI zend_string *php_unescape_html_entities(zend_string *str, int all, int fl inverse_map = unescape_inverse_map(all, flags); /* replace numeric entities */ - traverse_for_entities(ZSTR_VAL(str), ZSTR_LEN(str), ret, all, flags, inverse_map, charset); + traverse_for_entities(str, ret, all, flags, inverse_map, charset); return ret; } @@ -1320,6 +1356,9 @@ static void php_html_entities(INTERNAL_FUNCTION_PARAMETERS, int all) Z_PARAM_BOOL(double_encode); ZEND_PARSE_PARAMETERS_END(); + if (ZSTR_LEN(str) == 0) { + RETURN_EMPTY_STRING(); + } replaced = php_escape_html_entities_ex( (unsigned char*)ZSTR_VAL(str), ZSTR_LEN(str), all, (int) flags, hint_charset ? ZSTR_VAL(hint_charset) : NULL, double_encode, /* quiet */ 0); diff --git a/ext/standard/http_fopen_wrapper.c b/ext/standard/http_fopen_wrapper.c index 9fefe153622..85f5974be7e 100644 --- a/ext/standard/http_fopen_wrapper.c +++ b/ext/standard/http_fopen_wrapper.c @@ -638,13 +638,9 @@ finish: /* protocol version we are speaking */ if (context && (tmpzval = php_stream_context_get_option(context, "http", "protocol_version")) != NULL) { - char *protocol_version; - spprintf(&protocol_version, 0, "%.1F", zval_get_double(tmpzval)); - smart_str_appends(&req_buf, " HTTP/"); - smart_str_appends(&req_buf, protocol_version); + smart_str_append_printf(&req_buf, "%.1F", zval_get_double(tmpzval)); smart_str_appends(&req_buf, "\r\n"); - efree(protocol_version); } else { smart_str_appends(&req_buf, " HTTP/1.1\r\n"); } diff --git a/ext/standard/image.c b/ext/standard/image.c index eeb1f1fa281..97dcc437c83 100644 --- a/ext/standard/image.c +++ b/ext/standard/image.c @@ -51,24 +51,22 @@ PHPAPI const char php_sig_iff[4] = {'F','O','R','M'}; PHPAPI const char php_sig_ico[4] = {(char)0x00, (char)0x00, (char)0x01, (char)0x00}; PHPAPI const char php_sig_riff[4] = {'R', 'I', 'F', 'F'}; PHPAPI const char php_sig_webp[4] = {'W', 'E', 'B', 'P'}; +PHPAPI const char php_sig_ftyp[4] = {'f', 't', 'y', 'p'}; +PHPAPI const char php_sig_mif1[4] = {'m', 'i', 'f', '1'}; +PHPAPI const char php_sig_heic[4] = {'h', 'e', 'i', 'c'}; +PHPAPI const char php_sig_heix[4] = {'h', 'e', 'i', 'x'}; + +static zend_array php_image_handlers; +static int php_image_handler_next_id = IMAGE_FILETYPE_FIXED_COUNT; /* REMEMBER TO ADD MIME-TYPE TO FUNCTION php_image_type_to_mime_type */ /* PCX must check first 64bytes and byte 0=0x0a and byte2 < 0x06 */ -/* return info as a struct, to make expansion easier */ - -struct gfxinfo { - unsigned int width; - unsigned int height; - unsigned int bits; - unsigned int channels; -}; - /* {{{ php_handle_gif * routine to handle GIF files. If only everything were that easy... ;} */ -static struct gfxinfo *php_handle_gif (php_stream * stream) +static struct php_gfxinfo *php_handle_gif (php_stream * stream) { - struct gfxinfo *result = NULL; + struct php_gfxinfo *result = NULL; unsigned char dim[5]; if (php_stream_seek(stream, 3, SEEK_CUR)) @@ -77,7 +75,7 @@ static struct gfxinfo *php_handle_gif (php_stream * stream) if (php_stream_read(stream, (char*)dim, sizeof(dim)) != sizeof(dim)) return NULL; - result = (struct gfxinfo *) ecalloc(1, sizeof(struct gfxinfo)); + result = (struct php_gfxinfo *) ecalloc(1, sizeof(struct php_gfxinfo)); result->width = (unsigned int)dim[0] | (((unsigned int)dim[1])<<8); result->height = (unsigned int)dim[2] | (((unsigned int)dim[3])<<8); result->bits = dim[4]&0x80 ? ((((unsigned int)dim[4])&0x07) + 1) : 0; @@ -88,9 +86,9 @@ static struct gfxinfo *php_handle_gif (php_stream * stream) /* }}} */ /* {{{ php_handle_psd */ -static struct gfxinfo *php_handle_psd (php_stream * stream) +static struct php_gfxinfo *php_handle_psd (php_stream * stream) { - struct gfxinfo *result = NULL; + struct php_gfxinfo *result = NULL; unsigned char dim[8]; if (php_stream_seek(stream, 11, SEEK_CUR)) @@ -99,7 +97,7 @@ static struct gfxinfo *php_handle_psd (php_stream * stream) if (php_stream_read(stream, (char*)dim, sizeof(dim)) != sizeof(dim)) return NULL; - result = (struct gfxinfo *) ecalloc(1, sizeof(struct gfxinfo)); + result = (struct php_gfxinfo *) ecalloc(1, sizeof(struct php_gfxinfo)); result->height = (((unsigned int)dim[0]) << 24) + (((unsigned int)dim[1]) << 16) + (((unsigned int)dim[2]) << 8) + ((unsigned int)dim[3]); result->width = (((unsigned int)dim[4]) << 24) + (((unsigned int)dim[5]) << 16) + (((unsigned int)dim[6]) << 8) + ((unsigned int)dim[7]); @@ -108,9 +106,9 @@ static struct gfxinfo *php_handle_psd (php_stream * stream) /* }}} */ /* {{{ php_handle_bmp */ -static struct gfxinfo *php_handle_bmp (php_stream * stream) +static struct php_gfxinfo *php_handle_bmp (php_stream * stream) { - struct gfxinfo *result = NULL; + struct php_gfxinfo *result = NULL; unsigned char dim[16]; int size; @@ -122,12 +120,12 @@ static struct gfxinfo *php_handle_bmp (php_stream * stream) size = (((unsigned int)dim[ 3]) << 24) + (((unsigned int)dim[ 2]) << 16) + (((unsigned int)dim[ 1]) << 8) + ((unsigned int) dim[ 0]); if (size == 12) { - result = (struct gfxinfo *) ecalloc (1, sizeof(struct gfxinfo)); + result = (struct php_gfxinfo *) ecalloc (1, sizeof(struct php_gfxinfo)); result->width = (((unsigned int)dim[ 5]) << 8) + ((unsigned int) dim[ 4]); result->height = (((unsigned int)dim[ 7]) << 8) + ((unsigned int) dim[ 6]); result->bits = ((unsigned int)dim[11]); } else if (size > 12 && (size <= 64 || size == 108 || size == 124)) { - result = (struct gfxinfo *) ecalloc (1, sizeof(struct gfxinfo)); + result = (struct php_gfxinfo *) ecalloc (1, sizeof(struct php_gfxinfo)); result->width = (((unsigned int)dim[ 7]) << 24) + (((unsigned int)dim[ 6]) << 16) + (((unsigned int)dim[ 5]) << 8) + ((unsigned int) dim[ 4]); result->height = (((unsigned int)dim[11]) << 24) + (((unsigned int)dim[10]) << 16) + (((unsigned int)dim[ 9]) << 8) + ((unsigned int) dim[ 8]); result->height = abs((int32_t)result->height); @@ -158,9 +156,9 @@ static unsigned long int php_swf_get_bits (unsigned char* buffer, unsigned int p #if defined(HAVE_ZLIB) && !defined(COMPILE_DL_ZLIB) /* {{{ php_handle_swc */ -static struct gfxinfo *php_handle_swc(php_stream * stream) +static struct php_gfxinfo *php_handle_swc(php_stream * stream) { - struct gfxinfo *result = NULL; + struct php_gfxinfo *result = NULL; long bits; unsigned char a[64]; @@ -227,7 +225,7 @@ static struct gfxinfo *php_handle_swc(php_stream * stream) } if (!status) { - result = (struct gfxinfo *) ecalloc (1, sizeof (struct gfxinfo)); + result = (struct php_gfxinfo *) ecalloc (1, sizeof (struct php_gfxinfo)); bits = php_swf_get_bits (b, 0, 5); result->width = (php_swf_get_bits (b, 5 + bits, bits) - php_swf_get_bits (b, 5, bits)) / 20; @@ -244,9 +242,9 @@ static struct gfxinfo *php_handle_swc(php_stream * stream) #endif /* {{{ php_handle_swf */ -static struct gfxinfo *php_handle_swf (php_stream * stream) +static struct php_gfxinfo *php_handle_swf (php_stream * stream) { - struct gfxinfo *result = NULL; + struct php_gfxinfo *result = NULL; long bits; unsigned char a[32]; @@ -256,7 +254,7 @@ static struct gfxinfo *php_handle_swf (php_stream * stream) if (php_stream_read(stream, (char*)a, sizeof(a)) != sizeof(a)) return NULL; - result = (struct gfxinfo *) ecalloc (1, sizeof (struct gfxinfo)); + result = (struct php_gfxinfo *) ecalloc (1, sizeof (struct php_gfxinfo)); bits = php_swf_get_bits (a, 0, 5); result->width = (php_swf_get_bits (a, 5 + bits, bits) - php_swf_get_bits (a, 5, bits)) / 20; @@ -270,9 +268,9 @@ static struct gfxinfo *php_handle_swf (php_stream * stream) /* {{{ php_handle_png * routine to handle PNG files */ -static struct gfxinfo *php_handle_png (php_stream * stream) +static struct php_gfxinfo *php_handle_png (php_stream * stream) { - struct gfxinfo *result = NULL; + struct php_gfxinfo *result = NULL; unsigned char dim[9]; /* Width: 4 bytes * Height: 4 bytes @@ -289,7 +287,7 @@ static struct gfxinfo *php_handle_png (php_stream * stream) if((php_stream_read(stream, (char*)dim, sizeof(dim))) < sizeof(dim)) return NULL; - result = (struct gfxinfo *) ecalloc(1, sizeof(struct gfxinfo)); + result = (struct php_gfxinfo *) ecalloc(1, sizeof(struct php_gfxinfo)); result->width = (((unsigned int)dim[0]) << 24) + (((unsigned int)dim[1]) << 16) + (((unsigned int)dim[2]) << 8) + ((unsigned int)dim[3]); result->height = (((unsigned int)dim[4]) << 24) + (((unsigned int)dim[5]) << 16) + (((unsigned int)dim[6]) << 8) + ((unsigned int)dim[7]); result->bits = (unsigned int)dim[8]; @@ -448,9 +446,9 @@ static int php_read_APP(php_stream * stream, unsigned int marker, zval *info) /* {{{ php_handle_jpeg main loop to parse JPEG structure */ -static struct gfxinfo *php_handle_jpeg (php_stream * stream, zval *info) +static struct php_gfxinfo *php_handle_jpeg (php_stream * stream, zval *info) { - struct gfxinfo *result = NULL; + struct php_gfxinfo *result = NULL; unsigned int marker = M_PSEUDO; unsigned short length, ff_read=1; @@ -473,7 +471,7 @@ static struct gfxinfo *php_handle_jpeg (php_stream * stream, zval *info) case M_SOF15: if (result == NULL) { /* handle SOFn block */ - result = (struct gfxinfo *) ecalloc(1, sizeof(struct gfxinfo)); + result = (struct php_gfxinfo *) ecalloc(1, sizeof(struct php_gfxinfo)); length = php_read2(stream); result->bits = php_stream_getc(stream); result->height = php_read2(stream); @@ -576,9 +574,9 @@ static unsigned int php_read4(php_stream * stream) /* {{{ php_handle_jpc Main loop to parse JPEG2000 raw codestream structure */ -static struct gfxinfo *php_handle_jpc(php_stream * stream) +static struct php_gfxinfo *php_handle_jpc(php_stream * stream) { - struct gfxinfo *result = NULL; + struct php_gfxinfo *result = NULL; int highest_bit_depth, bit_depth; unsigned char first_marker_id; unsigned int i; @@ -599,7 +597,7 @@ static struct gfxinfo *php_handle_jpc(php_stream * stream) return NULL; } - result = (struct gfxinfo *)ecalloc(1, sizeof(struct gfxinfo)); + result = (struct php_gfxinfo *)ecalloc(1, sizeof(struct php_gfxinfo)); php_read2(stream); /* Lsiz */ php_read2(stream); /* Rsiz */ @@ -647,9 +645,9 @@ static struct gfxinfo *php_handle_jpc(php_stream * stream) /* {{{ php_handle_jp2 main loop to parse JPEG 2000 JP2 wrapper format structure */ -static struct gfxinfo *php_handle_jp2(php_stream *stream) +static struct php_gfxinfo *php_handle_jp2(php_stream *stream) { - struct gfxinfo *result = NULL; + struct php_gfxinfo *result = NULL; unsigned int box_length; unsigned int box_type; char jp2c_box_id[] = {(char)0x6a, (char)0x70, (char)0x32, (char)0x63}; @@ -773,9 +771,9 @@ static unsigned php_ifd_get32u(void *Long, int motorola_intel) /* {{{ php_handle_tiff main loop to parse TIFF structure */ -static struct gfxinfo *php_handle_tiff (php_stream * stream, zval *info, int motorola_intel) +static struct php_gfxinfo *php_handle_tiff (php_stream * stream, zval *info, int motorola_intel) { - struct gfxinfo *result = NULL; + struct php_gfxinfo *result = NULL; int i, num_entries; unsigned char *dir_entry; size_t ifd_size, dir_size, entry_value, width=0, height=0, ifd_addr; @@ -841,7 +839,7 @@ static struct gfxinfo *php_handle_tiff (php_stream * stream, zval *info, int mot efree(ifd_data); if ( width && height) { /* not the same when in for-loop */ - result = (struct gfxinfo *) ecalloc(1, sizeof(struct gfxinfo)); + result = (struct php_gfxinfo *) ecalloc(1, sizeof(struct php_gfxinfo)); result->height = height; result->width = width; result->bits = 0; @@ -853,9 +851,9 @@ static struct gfxinfo *php_handle_tiff (php_stream * stream, zval *info, int mot /* }}} */ /* {{{ php_handle_psd */ -static struct gfxinfo *php_handle_iff(php_stream * stream) +static struct php_gfxinfo *php_handle_iff(php_stream * stream) { - struct gfxinfo * result; + struct php_gfxinfo * result; unsigned char a[10]; int chunkId; int size; @@ -889,7 +887,7 @@ static struct gfxinfo *php_handle_iff(php_stream * stream) height = php_ifd_get16s(a+2, 1); bits = a[8] & 0xff; if (width > 0 && height > 0 && bits > 0 && bits < 33) { - result = (struct gfxinfo *) ecalloc(1, sizeof(struct gfxinfo)); + result = (struct php_gfxinfo *) ecalloc(1, sizeof(struct php_gfxinfo)); result->width = width; result->height = height; result->bits = bits; @@ -914,7 +912,7 @@ static struct gfxinfo *php_handle_iff(php_stream * stream) * int Number of columns * int Number of rows */ -static int php_get_wbmp(php_stream *stream, struct gfxinfo **result, int check) +static int php_get_wbmp(php_stream *stream, struct php_gfxinfo **result, int check) { int i, width = 0, height = 0; @@ -975,9 +973,9 @@ static int php_get_wbmp(php_stream *stream, struct gfxinfo **result, int check) /* }}} */ /* {{{ php_handle_wbmp */ -static struct gfxinfo *php_handle_wbmp(php_stream * stream) +static struct php_gfxinfo *php_handle_wbmp(php_stream * stream) { - struct gfxinfo *result = (struct gfxinfo *) ecalloc(1, sizeof(struct gfxinfo)); + struct php_gfxinfo *result = (struct php_gfxinfo *) ecalloc(1, sizeof(struct php_gfxinfo)); if (!php_get_wbmp(stream, &result, 0)) { efree(result); @@ -989,7 +987,7 @@ static struct gfxinfo *php_handle_wbmp(php_stream * stream) /* }}} */ /* {{{ php_get_xbm */ -static int php_get_xbm(php_stream *stream, struct gfxinfo **result) +static int php_get_xbm(php_stream *stream, struct php_gfxinfo **result) { char *fline; char *iname; @@ -1036,7 +1034,7 @@ static int php_get_xbm(php_stream *stream, struct gfxinfo **result) if (width && height) { if (result) { - *result = (struct gfxinfo *) ecalloc(1, sizeof(struct gfxinfo)); + *result = (struct php_gfxinfo *) ecalloc(1, sizeof(struct php_gfxinfo)); (*result)->width = width; (*result)->height = height; } @@ -1048,18 +1046,18 @@ static int php_get_xbm(php_stream *stream, struct gfxinfo **result) /* }}} */ /* {{{ php_handle_xbm */ -static struct gfxinfo *php_handle_xbm(php_stream * stream) +static struct php_gfxinfo *php_handle_xbm(php_stream * stream) { - struct gfxinfo *result; + struct php_gfxinfo *result; php_get_xbm(stream, &result); return result; } /* }}} */ /* {{{ php_handle_ico */ -static struct gfxinfo *php_handle_ico(php_stream * stream) +static struct php_gfxinfo *php_handle_ico(php_stream * stream) { - struct gfxinfo *result = NULL; + struct php_gfxinfo *result = NULL; unsigned char dim[16]; int num_icons = 0; @@ -1071,7 +1069,7 @@ static struct gfxinfo *php_handle_ico(php_stream * stream) if (num_icons < 1 || num_icons > 255) return NULL; - result = (struct gfxinfo *) ecalloc(1, sizeof(struct gfxinfo)); + result = (struct php_gfxinfo *) ecalloc(1, sizeof(struct php_gfxinfo)); while (num_icons > 0) { @@ -1098,9 +1096,9 @@ static struct gfxinfo *php_handle_ico(php_stream * stream) /* }}} */ /* {{{ php_handle_webp */ -static struct gfxinfo *php_handle_webp(php_stream * stream) +static struct php_gfxinfo *php_handle_webp(php_stream * stream) { - struct gfxinfo *result = NULL; + struct php_gfxinfo *result = NULL; const char sig[3] = {'V', 'P', '8'}; unsigned char buf[18]; char format; @@ -1121,7 +1119,7 @@ static struct gfxinfo *php_handle_webp(php_stream * stream) return NULL; } - result = (struct gfxinfo *) ecalloc(1, sizeof(struct gfxinfo)); + result = (struct php_gfxinfo *) ecalloc(1, sizeof(struct php_gfxinfo)); switch (format) { case ' ': @@ -1183,14 +1181,14 @@ static void php_avif_stream_skip(void* stream, size_t num_bytes) { * declared as invalid. Around 450 bytes are usually enough. * Transforms such as mirror and rotation are not applied on width and height. */ -static struct gfxinfo *php_handle_avif(php_stream * stream) { - struct gfxinfo* result = NULL; +static struct php_gfxinfo *php_handle_avif(php_stream * stream) { + struct php_gfxinfo* result = NULL; AvifInfoFeatures features; struct php_avif_stream avif_stream; avif_stream.stream = stream; if (AvifInfoGetFeaturesStream(&avif_stream, php_avif_stream_read, php_avif_stream_skip, &features) == kAvifInfoOk) { - result = (struct gfxinfo*)ecalloc(1, sizeof(struct gfxinfo)); + result = (struct php_gfxinfo*)ecalloc(1, sizeof(struct php_gfxinfo)); result->width = features.width; result->height = features.height; result->bits = features.bit_depth; @@ -1200,7 +1198,7 @@ static struct gfxinfo *php_handle_avif(php_stream * stream) { } /* }}} */ -/* {{{ php_is_image_avif +/* * Detect whether an image is of type AVIF * * Only the first "ftyp" box is read. @@ -1210,16 +1208,12 @@ bool php_is_image_avif(php_stream* stream) { struct php_avif_stream avif_stream; avif_stream.stream = stream; - if (AvifInfoIdentifyStream(&avif_stream, php_avif_stream_read, php_avif_stream_skip) == kAvifInfoOk) { - return 1; - } - return 0; + return AvifInfoIdentifyStream(&avif_stream, php_avif_stream_read, php_avif_stream_skip) == kAvifInfoOk; } -/* }}} */ /* {{{ php_image_type_to_mime_type * Convert internal image_type to mime type */ -PHPAPI char * php_image_type_to_mime_type(int image_type) +PHPAPI const char * php_image_type_to_mime_type(int image_type) { switch( image_type) { case IMAGE_FILETYPE_GIF: @@ -1254,7 +1248,15 @@ PHPAPI char * php_image_type_to_mime_type(int image_type) return "image/webp"; case IMAGE_FILETYPE_AVIF: return "image/avif"; - default: + case IMAGE_FILETYPE_HEIF: + return "image/heif"; + default: { + const struct php_image_handler *handler = zend_hash_index_find_ptr(&php_image_handlers, (zend_ulong) image_type); + if (handler) { + return handler->mime_type; + } + ZEND_FALLTHROUGH; + } case IMAGE_FILETYPE_UNKNOWN: return "application/octet-stream"; /* suppose binary format */ } @@ -1270,7 +1272,7 @@ PHP_FUNCTION(image_type_to_mime_type) Z_PARAM_LONG(p_image_type) ZEND_PARSE_PARAMETERS_END(); - ZVAL_STRING(return_value, (char*)php_image_type_to_mime_type(p_image_type)); + ZVAL_STRING(return_value, php_image_type_to_mime_type(p_image_type)); } /* }}} */ @@ -1339,6 +1341,16 @@ PHP_FUNCTION(image_type_to_extension) case IMAGE_FILETYPE_AVIF: imgext = ".avif"; break; + case IMAGE_FILETYPE_HEIF: + imgext = ".heif"; + break; + default: { + const struct php_image_handler *handler = zend_hash_index_find_ptr(&php_image_handlers, (zend_ulong) image_type); + if (handler) { + imgext = handler->extension; + } + break; + } } if (imgext) { @@ -1423,6 +1435,11 @@ PHPAPI int php_getimagetype(php_stream *stream, const char *input, char *filetyp return IMAGE_FILETYPE_JP2; } + if (twelve_bytes_read && !memcmp(filetype + 4, php_sig_ftyp, 4) && + (!memcmp(filetype + 8, php_sig_mif1, 4) || !memcmp(filetype + 8, php_sig_heic, 4) || !memcmp(filetype + 8, php_sig_heix, 4))) { + return IMAGE_FILETYPE_HEIF; + } + if (!php_stream_rewind(stream) && php_is_image_avif(stream)) { return IMAGE_FILETYPE_AVIF; } @@ -1441,6 +1458,15 @@ PHPAPI int php_getimagetype(php_stream *stream, const char *input, char *filetyp return IMAGE_FILETYPE_XBM; } + zend_ulong h; + zval *zv; + ZEND_HASH_FOREACH_NUM_KEY_VAL(&php_image_handlers, h, zv) { + const struct php_image_handler *handler = Z_PTR_P(zv); + if (handler->identify(stream) == SUCCESS) { + return (int) h; + } + } ZEND_HASH_FOREACH_END(); + return IMAGE_FILETYPE_UNKNOWN; } /* }}} */ @@ -1448,7 +1474,8 @@ PHPAPI int php_getimagetype(php_stream *stream, const char *input, char *filetyp static void php_getimagesize_from_stream(php_stream *stream, char *input, zval *info, INTERNAL_FUNCTION_PARAMETERS) /* {{{ */ { int itype = 0; - struct gfxinfo *result = NULL; + struct php_gfxinfo *result = NULL; + const char *mime_type = NULL; if (!stream) { RETURN_FALSE; @@ -1473,6 +1500,7 @@ static void php_getimagesize_from_stream(php_stream *stream, char *input, zval * result = php_handle_swf(stream); break; case IMAGE_FILETYPE_SWC: + /* TODO: with the new php_image_register_handler() APIs, this restriction could be solved */ #if defined(HAVE_ZLIB) && !defined(COMPILE_DL_ZLIB) result = php_handle_swc(stream); #else @@ -1515,19 +1543,35 @@ static void php_getimagesize_from_stream(php_stream *stream, char *input, zval * case IMAGE_FILETYPE_AVIF: result = php_handle_avif(stream); break; - default: + case IMAGE_FILETYPE_HEIF: + if (!php_stream_rewind(stream)) { + result = php_handle_avif(stream); + } + break; + default: { + struct php_image_handler* handler = zend_hash_index_find_ptr(&php_image_handlers, (zend_ulong) itype); + if (handler) { + result = handler->get_info(stream); + mime_type = handler->mime_type; + break; + } + ZEND_FALLTHROUGH; + } case IMAGE_FILETYPE_UNKNOWN: break; } if (result) { - char temp[MAX_LENGTH_OF_LONG * 2 + sizeof("width=\"\" height=\"\"")]; array_init(return_value); add_index_long(return_value, 0, result->width); add_index_long(return_value, 1, result->height); add_index_long(return_value, 2, itype); - snprintf(temp, sizeof(temp), "width=\"%d\" height=\"%d\"", result->width, result->height); - add_index_string(return_value, 3, temp); + if ((!result->width_unit || zend_string_equals_literal(result->width_unit, "px")) + && (!result->height_unit || zend_string_equals_literal(result->height_unit, "px"))) { + char temp[MAX_LENGTH_OF_LONG * 2 + sizeof("width=\"\" height=\"\"")]; + snprintf(temp, sizeof(temp), "width=\"%d\" height=\"%d\"", result->width, result->height); + add_index_string(return_value, 3, temp); + } if (result->bits != 0) { add_assoc_long(return_value, "bits", result->bits); @@ -1535,7 +1579,19 @@ static void php_getimagesize_from_stream(php_stream *stream, char *input, zval * if (result->channels != 0) { add_assoc_long(return_value, "channels", result->channels); } - add_assoc_string(return_value, "mime", (char*)php_image_type_to_mime_type(itype)); + add_assoc_string(return_value, "mime", mime_type ? mime_type : php_image_type_to_mime_type(itype)); + + if (result->width_unit) { + add_assoc_str(return_value, "width_unit", result->width_unit); + } else { + add_assoc_string(return_value, "width_unit", "px"); + } + if (result->height_unit) { + add_assoc_str(return_value, "height_unit", result->height_unit); + } else { + add_assoc_string(return_value, "height_unit", "px"); + } + efree(result); } else { RETURN_FALSE; @@ -1558,7 +1614,7 @@ static void php_getimagesize_from_any(INTERNAL_FUNCTION_PARAMETERS, int mode) { Z_PARAM_ZVAL(info) ZEND_PARSE_PARAMETERS_END(); - if (mode == FROM_PATH && CHECK_NULL_PATH(ZSTR_VAL(input), ZSTR_LEN(input))) { + if (mode == FROM_PATH && zend_str_has_nul_byte(input)) { zend_argument_value_error(1, "must not contain any null bytes"); RETURN_THROWS(); } @@ -1598,3 +1654,36 @@ PHP_FUNCTION(getimagesizefromstring) php_getimagesize_from_any(INTERNAL_FUNCTION_PARAM_PASSTHRU, FROM_DATA); } /* }}} */ + +PHP_MINIT_FUNCTION(image) +{ + zend_hash_init(&php_image_handlers, 4, NULL, NULL, true); + return SUCCESS; +} + +PHP_MSHUTDOWN_FUNCTION(image) +{ +#ifdef ZTS + if (!tsrm_is_main_thread()) { + return SUCCESS; + } +#endif + zend_hash_destroy(&php_image_handlers); + return SUCCESS; +} + +extern zend_module_entry basic_functions_module; + +int php_image_register_handler(const struct php_image_handler *handler) +{ + zend_hash_index_add_ptr(&php_image_handlers, (zend_ulong) php_image_handler_next_id, (void *) handler); + zend_register_long_constant(handler->const_name, strlen(handler->const_name), php_image_handler_next_id, CONST_PERSISTENT, basic_functions_module.module_number); + Z_LVAL_P(zend_get_constant_str(ZEND_STRL("IMAGETYPE_COUNT")))++; + return php_image_handler_next_id++; +} + +zend_result php_image_unregister_handler(int image_type) +{ + ZEND_ASSERT(image_type >= IMAGE_FILETYPE_FIXED_COUNT); + return zend_hash_index_del(&php_image_handlers, (zend_ulong) image_type); +} diff --git a/ext/standard/mail.c b/ext/standard/mail.c index 41e2a02078e..4263656a515 100644 --- a/ext/standard/mail.c +++ b/ext/standard/mail.c @@ -290,7 +290,7 @@ PHP_FUNCTION(mail) ZEND_PARSE_PARAMETERS_END(); if (headers_str) { - if (strlen(ZSTR_VAL(headers_str)) != ZSTR_LEN(headers_str)) { + if (UNEXPECTED(zend_str_has_nul_byte(headers_str))) { zend_argument_value_error(4, "must not contain any null bytes"); RETURN_THROWS(); } diff --git a/ext/standard/password.c b/ext/standard/password.c index 1e647bb301c..99dea810806 100644 --- a/ext/standard/password.c +++ b/ext/standard/password.c @@ -86,18 +86,18 @@ static zend_string* php_password_make_salt(size_t length) /* {{{ */ buffer = zend_string_alloc(length * 3 / 4 + 1, 0); if (FAILURE == php_random_bytes_throw(ZSTR_VAL(buffer), ZSTR_LEN(buffer))) { zend_value_error("Unable to generate salt"); - zend_string_release_ex(buffer, 0); + zend_string_efree(buffer); return NULL; } ret = zend_string_alloc(length, 0); if (php_password_salt_to64(ZSTR_VAL(buffer), ZSTR_LEN(buffer), length, ZSTR_VAL(ret)) == FAILURE) { zend_value_error("Generated salt too short"); - zend_string_release_ex(buffer, 0); - zend_string_release_ex(ret, 0); + zend_string_efree(buffer); + zend_string_efree(ret); return NULL; } - zend_string_release_ex(buffer, 0); + zend_string_efree(buffer); ZSTR_VAL(ret)[length] = 0; return ret; } diff --git a/ext/standard/php_image.h b/ext/standard/php_image.h index a41273e6745..6a4e0987d13 100644 --- a/ext/standard/php_image.h +++ b/ext/standard/php_image.h @@ -18,6 +18,9 @@ #ifndef PHP_IMAGE_H #define PHP_IMAGE_H +PHP_MINIT_FUNCTION(image); +PHP_MSHUTDOWN_FUNCTION(image); + /* {{{ enum image_filetype This enum is used to have ext/standard/image.c and ext/exif/exif.c use the same constants for file types. @@ -44,15 +47,44 @@ typedef enum IMAGE_FILETYPE_ICO, IMAGE_FILETYPE_WEBP, IMAGE_FILETYPE_AVIF, + IMAGE_FILETYPE_HEIF, /* WHEN EXTENDING: PLEASE ALSO REGISTER IN basic_function.stub.php */ - IMAGE_FILETYPE_COUNT + IMAGE_FILETYPE_FIXED_COUNT } image_filetype; /* }}} */ PHPAPI int php_getimagetype(php_stream *stream, const char *input, char *filetype); -PHPAPI char * php_image_type_to_mime_type(int image_type); +PHPAPI const char * php_image_type_to_mime_type(int image_type); PHPAPI bool php_is_image_avif(php_stream *stream); +/* return info as a struct, to make expansion easier */ +struct php_gfxinfo { + unsigned int width; + unsigned int height; + zend_string *width_unit; + zend_string *height_unit; + unsigned int bits; + unsigned int channels; +}; + +typedef zend_result (*php_image_identify)(php_stream *stream); +typedef struct php_gfxinfo *(*php_image_get_info)(php_stream *stream); + +struct php_image_handler { + const char *mime_type; + const char *extension; + const char *const_name; + php_image_identify identify; + php_image_get_info get_info; +}; + +#define PHP_IMAGE_CONST_NAME(suffix) ("IMAGETYPE_" suffix) + +/* This should only be called on module init */ +PHPAPI int php_image_register_handler(const struct php_image_handler *handler); +/* This should only be called on module shutdown */ +PHPAPI zend_result php_image_unregister_handler(int image_type); + #endif /* PHP_IMAGE_H */ diff --git a/ext/standard/proc_open.c b/ext/standard/proc_open.c index 06a3f916a84..690e23e0d35 100644 --- a/ext/standard/proc_open.c +++ b/ext/standard/proc_open.c @@ -136,11 +136,11 @@ fail: static int le_proc_open; /* Resource number for `proc` resources */ -/* {{{ _php_array_to_envp +/* {{{ php_array_to_envp * Process the `environment` argument to `proc_open` * Convert into data structures which can be passed to underlying OS APIs like `exec` on POSIX or * `CreateProcessW` on Win32 */ -static php_process_env _php_array_to_envp(zval *environment) +ZEND_ATTRIBUTE_NONNULL static php_process_env php_array_to_envp(const HashTable *environment) { zval *element; php_process_env env; @@ -154,13 +154,9 @@ static php_process_env _php_array_to_envp(zval *environment) memset(&env, 0, sizeof(env)); - if (!environment) { - return env; - } + uint32_t cnt = zend_hash_num_elements(environment); - uint32_t cnt = zend_hash_num_elements(Z_ARRVAL_P(environment)); - - if (cnt < 1) { + if (cnt == 0) { #ifndef PHP_WIN32 env.envarray = (char **) ecalloc(1, sizeof(char *)); #endif @@ -172,7 +168,7 @@ static php_process_env _php_array_to_envp(zval *environment) zend_hash_init(env_hash, cnt, NULL, NULL, 0); /* first, we have to get the size of all the elements in the hash */ - ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(environment), key, element) { + ZEND_HASH_FOREACH_STR_KEY_VAL(environment, key, element) { str = zval_get_string(element); if (ZSTR_LEN(str) == 0) { @@ -221,7 +217,7 @@ static php_process_env _php_array_to_envp(zval *environment) /* }}} */ /* {{{ _php_free_envp - * Free the structures allocated by `_php_array_to_envp` */ + * Free the structures allocated by php_array_to_envp */ static void _php_free_envp(php_process_env env) { #ifndef PHP_WIN32 @@ -506,7 +502,7 @@ typedef struct _descriptorspec_item { int mode_flags; /* mode for opening FDs: r/o, r/w, binary (on Win32), etc */ } descriptorspec_item; -static zend_string *get_valid_arg_string(zval *zv, int elem_num) { +static zend_string *get_valid_arg_string(zval *zv, uint32_t elem_num) { zend_string *str = zval_get_string(zv); if (!str) { return NULL; @@ -518,7 +514,7 @@ static zend_string *get_valid_arg_string(zval *zv, int elem_num) { return NULL; } - if (strlen(ZSTR_VAL(str)) != ZSTR_LEN(str)) { + if (zend_str_has_nul_byte(str)) { zend_value_error("Command array element %d contains a null byte", elem_num); zend_string_release(str); return NULL; @@ -630,7 +626,7 @@ static zend_string *create_win_command_from_args(HashTable *args) zval *arg_zv; bool is_prog_name = true; bool is_cmd_execution = false; - int elem_num = 0; + uint32_t elem_num = 0; ZEND_HASH_FOREACH_VAL(args, arg_zv) { zend_string *arg_str = get_valid_arg_string(arg_zv, ++elem_num); @@ -778,11 +774,11 @@ static zend_result convert_command_to_use_shell(wchar_t **cmdw, size_t cmdw_len) #ifndef PHP_WIN32 /* Convert command parameter array passed as first argument to `proc_open` into command string */ -static zend_string* get_command_from_array(HashTable *array, char ***argv, int num_elems) +static zend_string* get_command_from_array(const HashTable *array, char ***argv, uint32_t num_elems) { zval *arg_zv; zend_string *command = NULL; - int i = 0; + uint32_t i = 0; *argv = safe_emalloc(sizeof(char *), num_elems + 1, 0); @@ -810,16 +806,16 @@ static zend_string* get_command_from_array(HashTable *array, char ***argv, int n } #endif -static descriptorspec_item* alloc_descriptor_array(HashTable *descriptorspec) +static descriptorspec_item* alloc_descriptor_array(const HashTable *descriptorspec) { uint32_t ndescriptors = zend_hash_num_elements(descriptorspec); return ecalloc(ndescriptors, sizeof(descriptorspec_item)); } -static zend_string* get_string_parameter(zval *array, int index, char *param_name) +static zend_string* get_string_parameter(const HashTable *ht, unsigned int index, const char *param_name) { zval *array_item; - if ((array_item = zend_hash_index_find(Z_ARRVAL_P(array), index)) == NULL) { + if ((array_item = zend_hash_index_find(ht, index)) == NULL) { zend_value_error("Missing %s", param_name); return NULL; } @@ -995,7 +991,7 @@ static zend_result dup_proc_descriptor(php_file_descriptor_t from, php_file_desc } static zend_result redirect_proc_descriptor(descriptorspec_item *desc, int target, - descriptorspec_item *descriptors, int ndesc, int nindex) + const descriptorspec_item *descriptors, int ndesc, int nindex) { php_file_descriptor_t redirect_to = PHP_INVALID_FD; @@ -1030,9 +1026,9 @@ static zend_result redirect_proc_descriptor(descriptorspec_item *desc, int targe } /* Process one item from `$descriptorspec` argument to `proc_open` */ -static zend_result set_proc_descriptor_from_array(zval *descitem, descriptorspec_item *descriptors, +static zend_result set_proc_descriptor_from_array(const HashTable *ht, descriptorspec_item *descriptors, int ndesc, int nindex, int *pty_master_fd, int *pty_slave_fd) { - zend_string *ztype = get_string_parameter(descitem, 0, "handle qualifier"); + zend_string *ztype = get_string_parameter(ht, 0, "handle qualifier"); if (!ztype) { return FAILURE; } @@ -1042,7 +1038,7 @@ static zend_result set_proc_descriptor_from_array(zval *descitem, descriptorspec if (zend_string_equals_literal(ztype, "pipe")) { /* Set descriptor to pipe */ - zmode = get_string_parameter(descitem, 1, "mode parameter for 'pipe'"); + zmode = get_string_parameter(ht, 1, "mode parameter for 'pipe'"); if (zmode == NULL) { goto finish; } @@ -1052,16 +1048,16 @@ static zend_result set_proc_descriptor_from_array(zval *descitem, descriptorspec retval = set_proc_descriptor_to_socket(&descriptors[ndesc]); } else if (zend_string_equals(ztype, ZSTR_KNOWN(ZEND_STR_FILE))) { /* Set descriptor to file */ - if ((zfile = get_string_parameter(descitem, 1, "file name parameter for 'file'")) == NULL) { + if ((zfile = get_string_parameter(ht, 1, "file name parameter for 'file'")) == NULL) { goto finish; } - if ((zmode = get_string_parameter(descitem, 2, "mode parameter for 'file'")) == NULL) { + if ((zmode = get_string_parameter(ht, 2, "mode parameter for 'file'")) == NULL) { goto finish; } retval = set_proc_descriptor_to_file(&descriptors[ndesc], zfile, zmode); } else if (zend_string_equals_literal(ztype, "redirect")) { /* Redirect descriptor to whatever another descriptor is set to */ - zval *ztarget = zend_hash_index_find_deref(Z_ARRVAL_P(descitem), 1); + zval *ztarget = zend_hash_index_find_deref(ht, 1); if (!ztarget) { zend_value_error("Missing redirection target"); goto finish; @@ -1116,7 +1112,7 @@ static zend_result set_proc_descriptor_from_resource(zval *resource, descriptors #ifndef PHP_WIN32 #if defined(USE_POSIX_SPAWN) -static zend_result close_parentends_of_pipes(posix_spawn_file_actions_t * actions, descriptorspec_item *descriptors, int ndesc) +static zend_result close_parentends_of_pipes(posix_spawn_file_actions_t * actions, const descriptorspec_item *descriptors, int ndesc) { int r; for (int i = 0; i < ndesc; i++) { @@ -1200,9 +1196,10 @@ PHP_FUNCTION(proc_open) HashTable *command_ht; HashTable *descriptorspec; /* Mandatory argument */ zval *pipes; /* Mandatory argument */ - char *cwd = NULL; /* Optional argument */ - size_t cwd_len = 0; /* Optional argument */ - zval *environment = NULL, *other_options = NULL; /* Optional arguments */ + char *cwd = NULL; /* Optional argument */ + size_t cwd_len = 0; /* Optional argument */ + HashTable *environment = NULL; /* Optional arguments */ + zval *other_options = NULL; /* Optional arguments */ php_process_env env; int ndesc = 0; @@ -1239,7 +1236,7 @@ PHP_FUNCTION(proc_open) Z_PARAM_ZVAL(pipes) Z_PARAM_OPTIONAL Z_PARAM_STRING_OR_NULL(cwd, cwd_len) - Z_PARAM_ARRAY_OR_NULL(environment) + Z_PARAM_ARRAY_HT_OR_NULL(environment) Z_PARAM_ARRAY_OR_NULL(other_options) ZEND_PARSE_PARAMETERS_END(); @@ -1282,7 +1279,7 @@ PHP_FUNCTION(proc_open) #endif if (environment) { - env = _php_array_to_envp(environment); + env = php_array_to_envp(environment); } descriptors = alloc_descriptor_array(descriptorspec); @@ -1302,7 +1299,7 @@ PHP_FUNCTION(proc_open) goto exit_fail; } } else if (Z_TYPE_P(descitem) == IS_ARRAY) { - if (set_proc_descriptor_from_array(descitem, descriptors, ndesc, (int)nindex, + if (set_proc_descriptor_from_array(Z_ARRVAL_P(descitem), descriptors, ndesc, (int)nindex, &pty_master_fd, &pty_slave_fd) == FAILURE) { goto exit_fail; } diff --git a/ext/standard/streamsfuncs.c b/ext/standard/streamsfuncs.c index 2e38965232c..506ce0dafed 100644 --- a/ext/standard/streamsfuncs.c +++ b/ext/standard/streamsfuncs.c @@ -99,7 +99,6 @@ PHP_FUNCTION(stream_socket_client) zval *zerrno = NULL, *zerrstr = NULL, *zcontext = NULL; double timeout; bool timeout_is_null = 1; - php_timeout_ull conv; struct timeval tv; char *hashkey = NULL; php_stream *stream = NULL; @@ -138,7 +137,7 @@ PHP_FUNCTION(stream_socket_client) if (timeout < 0.0 || timeout >= (double) PHP_TIMEOUT_ULL_MAX / 1000000.0) { tv_pointer = NULL; } else { - conv = (php_timeout_ull) (timeout * 1000000.0); + php_timeout_ull conv = (php_timeout_ull) (timeout * 1000000.0); #ifdef PHP_WIN32 tv.tv_sec = (long)(conv / 1000000); tv.tv_usec = (long)(conv % 1000000); @@ -262,7 +261,6 @@ PHP_FUNCTION(stream_socket_accept) bool timeout_is_null = 1; zval *zpeername = NULL; zend_string *peername = NULL; - php_timeout_ull conv; struct timeval tv; php_stream *stream = NULL, *clistream = NULL; zend_string *errstr = NULL; @@ -286,7 +284,7 @@ PHP_FUNCTION(stream_socket_accept) if (timeout < 0.0 || timeout >= (double) PHP_TIMEOUT_ULL_MAX / 1000000.0) { tv_pointer = NULL; } else { - conv = (php_timeout_ull) (timeout * 1000000.0); + php_timeout_ull conv = (php_timeout_ull) (timeout * 1000000.0); #ifdef PHP_WIN32 tv.tv_sec = (long)(conv / 1000000); tv.tv_usec = (long)(conv % 1000000); @@ -484,7 +482,6 @@ PHP_FUNCTION(stream_copy_to_stream) zend_long maxlen, pos = 0; bool maxlen_is_null = 1; size_t len; - int ret; ZEND_PARSE_PARAMETERS_START(2, 4) PHP_Z_PARAM_STREAM(src) @@ -503,9 +500,7 @@ PHP_FUNCTION(stream_copy_to_stream) RETURN_FALSE; } - ret = php_stream_copy_to_stream_ex(src, dest, maxlen, &len); - - if (ret != SUCCESS) { + if (php_stream_copy_to_stream_ex(src, dest, maxlen, &len) != SUCCESS) { RETURN_FALSE; } RETURN_LONG(len); @@ -534,9 +529,9 @@ PHP_FUNCTION(stream_get_meta_data) add_assoc_zval(return_value, "wrapper_data", &stream->wrapperdata); } if (stream->wrapper) { - add_assoc_string(return_value, "wrapper_type", (char *)stream->wrapper->wops->label); + add_assoc_string(return_value, "wrapper_type", stream->wrapper->wops->label); } - add_assoc_string(return_value, "stream_type", (char *)stream->ops->label); + add_assoc_string(return_value, "stream_type", stream->ops->label); add_assoc_string(return_value, "mode", stream->mode); @@ -548,7 +543,7 @@ PHP_FUNCTION(stream_get_meta_data) array_init(newval); for (filter = stream->filterhead; filter != NULL; filter = filter->next) { - add_next_index_string(newval, (char *)filter->fops->label); + add_next_index_string(newval, filter->fops->label); } add_assoc_zval(return_value, "filters", newval); @@ -568,13 +563,13 @@ PHP_FUNCTION(stream_get_meta_data) /* {{{ Retrieves list of registered socket transports */ PHP_FUNCTION(stream_get_transports) { - HashTable *stream_xport_hash; - zend_string *stream_xport; ZEND_PARSE_PARAMETERS_NONE(); - stream_xport_hash = php_stream_xport_get_hash(); array_init(return_value); + + const HashTable *stream_xport_hash = php_stream_xport_get_hash(); + zend_string *stream_xport; ZEND_HASH_MAP_FOREACH_STR_KEY(stream_xport_hash, stream_xport) { add_next_index_str(return_value, zend_string_copy(stream_xport)); } ZEND_HASH_FOREACH_END(); @@ -584,13 +579,12 @@ PHP_FUNCTION(stream_get_transports) /* {{{ Retrieves list of registered stream wrappers */ PHP_FUNCTION(stream_get_wrappers) { - HashTable *url_stream_wrappers_hash; - zend_string *stream_protocol; - ZEND_PARSE_PARAMETERS_NONE(); - url_stream_wrappers_hash = php_stream_get_url_stream_wrappers_hash(); array_init(return_value); + + const HashTable *url_stream_wrappers_hash = php_stream_get_url_stream_wrappers_hash(); + zend_string *stream_protocol; ZEND_HASH_MAP_FOREACH_STR_KEY(url_stream_wrappers_hash, stream_protocol) { if (stream_protocol) { add_next_index_str(return_value, zend_string_copy(stream_protocol)); @@ -601,17 +595,13 @@ PHP_FUNCTION(stream_get_wrappers) /* }}} */ /* {{{ stream_select related functions */ -static int stream_array_to_fd_set(zval *stream_array, fd_set *fds, php_socket_t *max_fd) +static int stream_array_to_fd_set(const HashTable *stream_array, fd_set *fds, php_socket_t *max_fd) { zval *elem; php_stream *stream; int cnt = 0; - if (Z_TYPE_P(stream_array) != IS_ARRAY) { - return 0; - } - - ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(stream_array), elem) { + ZEND_HASH_FOREACH_VAL(stream_array, elem) { /* Temporary int fd is needed for the STREAM data type on windows, passing this_fd directly to php_stream_cast() would eventually bring a wrong result on x64. php_stream_cast() casts to int internally, and this will leave the higher bits of a SOCKET variable uninitialized on systems with little endian. */ @@ -640,7 +630,7 @@ static int stream_array_to_fd_set(zval *stream_array, fd_set *fds, php_socket_t return cnt ? 1 : 0; } -static int stream_array_from_fd_set(zval *stream_array, fd_set *fds) +static int stream_array_from_fd_set(zval *stream_array, const fd_set *fds) { zval *elem, *dest_elem; HashTable *ht; @@ -649,9 +639,7 @@ static int stream_array_from_fd_set(zval *stream_array, fd_set *fds) zend_string *key; zend_ulong num_ind; - if (Z_TYPE_P(stream_array) != IS_ARRAY) { - return 0; - } + ZEND_ASSERT(Z_TYPE_P(stream_array) == IS_ARRAY); ht = zend_new_array(zend_hash_num_elements(Z_ARRVAL_P(stream_array))); ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(stream_array), num_ind, key, elem) { @@ -677,7 +665,6 @@ static int stream_array_from_fd_set(zval *stream_array, fd_set *fds) zval_add_ref(dest_elem); ret++; - continue; } } } ZEND_HASH_FOREACH_END(); @@ -698,9 +685,7 @@ static int stream_array_emulate_read_fd_set(zval *stream_array) zend_ulong num_ind; zend_string *key; - if (Z_TYPE_P(stream_array) != IS_ARRAY) { - return 0; - } + ZEND_ASSERT(Z_TYPE_P(stream_array) == IS_ARRAY); ht = zend_new_array(zend_hash_num_elements(Z_ARRVAL_P(stream_array))); ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(stream_array), num_ind, key, elem) { @@ -723,7 +708,6 @@ static int stream_array_emulate_read_fd_set(zval *stream_array) } zval_add_ref(dest_elem); ret++; - continue; } } ZEND_HASH_FOREACH_END(); @@ -766,21 +750,21 @@ PHP_FUNCTION(stream_select) FD_ZERO(&efds); if (r_array != NULL) { - set_count = stream_array_to_fd_set(r_array, &rfds, &max_fd); + set_count = stream_array_to_fd_set(Z_ARR_P(r_array), &rfds, &max_fd); if (set_count > max_set_count) max_set_count = set_count; sets += set_count; } if (w_array != NULL) { - set_count = stream_array_to_fd_set(w_array, &wfds, &max_fd); + set_count = stream_array_to_fd_set(Z_ARR_P(w_array), &wfds, &max_fd); if (set_count > max_set_count) max_set_count = set_count; sets += set_count; } if (e_array != NULL) { - set_count = stream_array_to_fd_set(e_array, &efds, &max_fd); + set_count = stream_array_to_fd_set(Z_ARR_P(e_array), &efds, &max_fd); if (set_count > max_set_count) max_set_count = set_count; sets += set_count; @@ -869,22 +853,20 @@ static void user_space_stream_notifier(php_stream_context *context, int notifyco ZVAL_LONG(&zvs[4], bytes_sofar); ZVAL_LONG(&zvs[5], bytes_max); - zend_call_known_fcc(context->notifier->fcc, NULL, 6, zvs, NULL); + zend_call_known_fcc(context->notifier->ptr, NULL, 6, zvs, NULL); /* Free refcounted string parameter */ zval_ptr_dtor_str(&zvs[2]); } static void user_space_stream_notifier_dtor(php_stream_notifier *notifier) { - ZEND_ASSERT(notifier); - ZEND_ASSERT(notifier->fcc); - ZEND_ASSERT(notifier->fcc->function_handler); - zend_fcc_dtor(notifier->fcc); - efree(notifier->fcc); - notifier->fcc = NULL; + zend_fcall_info_cache *fcc = notifier->ptr; + zend_fcc_dtor(fcc); + efree(notifier->ptr); + notifier->ptr = NULL; } -static zend_result parse_context_options(php_stream_context *context, HashTable *options) +static zend_result parse_context_options(php_stream_context *context, const HashTable *options) { zval *wval, *oval; zend_string *wkey, *okey; @@ -908,7 +890,7 @@ static zend_result parse_context_options(php_stream_context *context, HashTable return SUCCESS; } -static zend_result parse_context_params(php_stream_context *context, HashTable *params) +static zend_result parse_context_params(php_stream_context *context, const HashTable *params) { zval *tmp; @@ -931,7 +913,7 @@ static zend_result parse_context_params(php_stream_context *context, HashTable * context->notifier = php_stream_notification_alloc(); context->notifier->func = user_space_stream_notifier; - context->notifier->fcc = fcc; + context->notifier->ptr = fcc; context->notifier->dtor = user_space_stream_notifier_dtor; } if (NULL != (tmp = zend_hash_str_find(params, "options", sizeof("options")-1))) { @@ -1128,10 +1110,10 @@ PHP_FUNCTION(stream_context_get_params) } array_init(return_value); - if (context->notifier && context->notifier->fcc) { - ZEND_ASSERT(context->notifier->func == user_space_stream_notifier); + if (context->notifier && context->notifier->func == user_space_stream_notifier) { + zend_fcall_info_cache *fcc = context->notifier->ptr; zval fn; - zend_get_callable_zval_from_fcc(context->notifier->fcc, &fn); + zend_get_callable_zval_from_fcc(fcc, &fn); add_assoc_zval_ex(return_value, ZEND_STRL("notification"), &fn); } Z_TRY_ADDREF(context->options); @@ -1220,7 +1202,7 @@ PHP_FUNCTION(stream_context_create) /* }}} */ /* {{{ streams filter functions */ -static void apply_filter_to_stream(int append, INTERNAL_FUNCTION_PARAMETERS) +static void apply_filter_to_stream(bool append, INTERNAL_FUNCTION_PARAMETERS) { php_stream *stream; char *filtername; @@ -1228,7 +1210,6 @@ static void apply_filter_to_stream(int append, INTERNAL_FUNCTION_PARAMETERS) zend_long read_write = 0; zval *filterparams = NULL; php_stream_filter *filter = NULL; - int ret; ZEND_PARSE_PARAMETERS_START(2, 4) PHP_Z_PARAM_STREAM(stream) @@ -1259,13 +1240,13 @@ static void apply_filter_to_stream(int append, INTERNAL_FUNCTION_PARAMETERS) } if (append) { - ret = php_stream_filter_append_ex(&stream->readfilters, filter); + zend_result ret = php_stream_filter_append_ex(&stream->readfilters, filter); + if (ret != SUCCESS) { + php_stream_filter_remove(filter, 1); + RETURN_FALSE; + } } else { - ret = php_stream_filter_prepend_ex(&stream->readfilters, filter); - } - if (ret != SUCCESS) { - php_stream_filter_remove(filter, 1); - RETURN_FALSE; + php_stream_filter_prepend_ex(&stream->readfilters, filter); } } @@ -1276,13 +1257,13 @@ static void apply_filter_to_stream(int append, INTERNAL_FUNCTION_PARAMETERS) } if (append) { - ret = php_stream_filter_append_ex(&stream->writefilters, filter); + zend_result ret = php_stream_filter_append_ex(&stream->writefilters, filter); + if (ret != SUCCESS) { + php_stream_filter_remove(filter, 1); + RETURN_FALSE; + } } else { - ret = php_stream_filter_prepend_ex(&stream->writefilters, filter); - } - if (ret != SUCCESS) { - php_stream_filter_remove(filter, 1); - RETURN_FALSE; + php_stream_filter_prepend_ex(&stream->writefilters, filter); } } @@ -1380,11 +1361,7 @@ PHP_FUNCTION(stream_set_blocking) Z_PARAM_BOOL(block) ZEND_PARSE_PARAMETERS_END(); - if (php_stream_set_option(stream, PHP_STREAM_OPTION_BLOCKING, block, NULL) == -1) { - RETURN_FALSE; - } - - RETURN_TRUE; + RETURN_BOOL(-1 != php_stream_set_option(stream, PHP_STREAM_OPTION_BLOCKING, block, NULL)); } /* }}} */ @@ -1425,11 +1402,7 @@ PHP_FUNCTION(stream_set_timeout) } #endif - if (PHP_STREAM_OPTION_RETURN_OK == php_stream_set_option(stream, PHP_STREAM_OPTION_READ_TIMEOUT, 0, &t)) { - RETURN_TRUE; - } - - RETURN_FALSE; + RETURN_BOOL(PHP_STREAM_OPTION_RETURN_OK == php_stream_set_option(stream, PHP_STREAM_OPTION_READ_TIMEOUT, 0, &t)); } #endif /* HAVE_SYS_TIME_H || defined(PHP_WIN32) */ /* }}} */ @@ -1605,11 +1578,7 @@ PHP_FUNCTION(stream_is_local) wrapper = php_stream_locate_url_wrapper(Z_STRVAL_P(zstream), NULL, 0); } - if (!wrapper) { - RETURN_FALSE; - } - - RETURN_BOOL(wrapper->is_url==0); + RETURN_BOOL(wrapper && wrapper->is_url == 0); } /* }}} */ @@ -1622,11 +1591,7 @@ PHP_FUNCTION(stream_supports_lock) PHP_Z_PARAM_STREAM(stream) ZEND_PARSE_PARAMETERS_END(); - if (!php_stream_supports_lock(stream)) { - RETURN_FALSE; - } - - RETURN_TRUE; + RETURN_BOOL(php_stream_supports_lock(stream)); } /* {{{ Check if a stream is a TTY. */ @@ -1653,15 +1618,13 @@ PHP_FUNCTION(stream_isatty) #ifdef PHP_WIN32 /* Check if the Windows standard handle is redirected to file */ - RETVAL_BOOL(php_win32_console_fileno_is_console(fileno)); + RETURN_BOOL(php_win32_console_fileno_is_console(fileno)); #elif defined(HAVE_UNISTD_H) /* Check if the file descriptor identifier is a terminal */ - RETVAL_BOOL(isatty(fileno)); + RETURN_BOOL(isatty(fileno)); #else - { - zend_stat_t stat = {0}; - RETVAL_BOOL(zend_fstat(fileno, &stat) == 0 && (stat.st_mode & /*S_IFMT*/0170000) == /*S_IFCHR*/0020000); - } + zend_stat_t stat = {0}; + RETURN_BOOL(zend_fstat(fileno, &stat) == 0 && (stat.st_mode & /*S_IFMT*/0170000) == /*S_IFCHR*/0020000); #endif } @@ -1707,21 +1670,10 @@ PHP_FUNCTION(sapi_windows_vt100_support) if (enable_is_null) { /* Check if the Windows standard handle has VT100 control codes enabled */ - if (php_win32_console_fileno_has_vt100(fileno)) { - RETURN_TRUE; - } - else { - RETURN_FALSE; - } - } - else { + RETURN_BOOL(php_win32_console_fileno_has_vt100(fileno)); + } else { /* Enable/disable VT100 control codes support for the specified Windows standard handle */ - if (php_win32_console_fileno_set_vt100(fileno, enable ? TRUE : FALSE)) { - RETURN_TRUE; - } - else { - RETURN_FALSE; - } + RETURN_BOOL(php_win32_console_fileno_set_vt100(fileno, enable ? TRUE : FALSE)); } } #endif diff --git a/ext/standard/string.c b/ext/standard/string.c index 4bc56f550fe..a5acb28ddb3 100644 --- a/ext/standard/string.c +++ b/ext/standard/string.c @@ -2665,6 +2665,12 @@ PHP_FUNCTION(chr) Z_PARAM_LONG(c) ZEND_PARSE_PARAMETERS_END(); + if (UNEXPECTED(c < 0 || c > 255)) { + php_error_docref(NULL, E_DEPRECATED, + "Providing a value not in-between 0 and 255 is deprecated," + " this is because a byte value must be in the [0, 255] interval." + " The value used will be constrained using %% 256"); + } c &= 0xff; RETURN_CHAR(c); } diff --git a/ext/standard/tests/array/array_diff_assoc_variation1.phpt b/ext/standard/tests/array/array_diff_assoc_variation1.phpt deleted file mode 100644 index b16baa300f5..00000000000 --- a/ext/standard/tests/array/array_diff_assoc_variation1.phpt +++ /dev/null @@ -1,179 +0,0 @@ ---TEST-- -Test array_diff_assoc() function : usage variations - unexpected values for 'array1' argument ---FILE-- -getMessage(), "\n"; - } - $iterator++; -}; -fclose($fp); -echo "Done"; -?> ---EXPECT-- -*** Testing array_diff_assoc() : usage variations *** - --- Iteration 1 -- -array_diff_assoc(): Argument #1 ($array) must be of type array, int given - --- Iteration 2 -- -array_diff_assoc(): Argument #1 ($array) must be of type array, int given - --- Iteration 3 -- -array_diff_assoc(): Argument #1 ($array) must be of type array, int given - --- Iteration 4 -- -array_diff_assoc(): Argument #1 ($array) must be of type array, int given - --- Iteration 5 -- -array_diff_assoc(): Argument #1 ($array) must be of type array, float given - --- Iteration 6 -- -array_diff_assoc(): Argument #1 ($array) must be of type array, float given - --- Iteration 7 -- -array_diff_assoc(): Argument #1 ($array) must be of type array, float given - --- Iteration 8 -- -array_diff_assoc(): Argument #1 ($array) must be of type array, float given - --- Iteration 9 -- -array_diff_assoc(): Argument #1 ($array) must be of type array, float given - --- Iteration 10 -- -array_diff_assoc(): Argument #1 ($array) must be of type array, null given - --- Iteration 11 -- -array_diff_assoc(): Argument #1 ($array) must be of type array, null given - --- Iteration 12 -- -array_diff_assoc(): Argument #1 ($array) must be of type array, true given - --- Iteration 13 -- -array_diff_assoc(): Argument #1 ($array) must be of type array, false given - --- Iteration 14 -- -array_diff_assoc(): Argument #1 ($array) must be of type array, true given - --- Iteration 15 -- -array_diff_assoc(): Argument #1 ($array) must be of type array, false given - --- Iteration 16 -- -array_diff_assoc(): Argument #1 ($array) must be of type array, string given - --- Iteration 17 -- -array_diff_assoc(): Argument #1 ($array) must be of type array, string given - --- Iteration 18 -- -array_diff_assoc(): Argument #1 ($array) must be of type array, string given - --- Iteration 19 -- -array_diff_assoc(): Argument #1 ($array) must be of type array, string given - --- Iteration 20 -- -array_diff_assoc(): Argument #1 ($array) must be of type array, string given - --- Iteration 21 -- -array_diff_assoc(): Argument #1 ($array) must be of type array, string given - --- Iteration 22 -- -array_diff_assoc(): Argument #1 ($array) must be of type array, string given - --- Iteration 23 -- -array_diff_assoc(): Argument #1 ($array) must be of type array, classA given - --- Iteration 24 -- -array_diff_assoc(): Argument #1 ($array) must be of type array, null given - --- Iteration 25 -- -array_diff_assoc(): Argument #1 ($array) must be of type array, null given - --- Iteration 26 -- -array_diff_assoc(): Argument #1 ($array) must be of type array, resource given -Done diff --git a/ext/standard/tests/array/array_diff_assoc_variation2.phpt b/ext/standard/tests/array/array_diff_assoc_variation2.phpt deleted file mode 100644 index a0b1bac329d..00000000000 --- a/ext/standard/tests/array/array_diff_assoc_variation2.phpt +++ /dev/null @@ -1,179 +0,0 @@ ---TEST-- -Test array_diff_assoc() function : usage variations - unexpected values for 'array1' argument ---FILE-- -getMessage(), "\n"; - } - $iterator++; -}; -fclose($fp); -echo "Done"; -?> ---EXPECT-- -*** Testing array_diff_assoc() : usage variations *** - --- Iteration 1 -- -array_diff_assoc(): Argument #2 must be of type array, int given - --- Iteration 2 -- -array_diff_assoc(): Argument #2 must be of type array, int given - --- Iteration 3 -- -array_diff_assoc(): Argument #2 must be of type array, int given - --- Iteration 4 -- -array_diff_assoc(): Argument #2 must be of type array, int given - --- Iteration 5 -- -array_diff_assoc(): Argument #2 must be of type array, float given - --- Iteration 6 -- -array_diff_assoc(): Argument #2 must be of type array, float given - --- Iteration 7 -- -array_diff_assoc(): Argument #2 must be of type array, float given - --- Iteration 8 -- -array_diff_assoc(): Argument #2 must be of type array, float given - --- Iteration 9 -- -array_diff_assoc(): Argument #2 must be of type array, float given - --- Iteration 10 -- -array_diff_assoc(): Argument #2 must be of type array, null given - --- Iteration 11 -- -array_diff_assoc(): Argument #2 must be of type array, null given - --- Iteration 12 -- -array_diff_assoc(): Argument #2 must be of type array, true given - --- Iteration 13 -- -array_diff_assoc(): Argument #2 must be of type array, false given - --- Iteration 14 -- -array_diff_assoc(): Argument #2 must be of type array, true given - --- Iteration 15 -- -array_diff_assoc(): Argument #2 must be of type array, false given - --- Iteration 16 -- -array_diff_assoc(): Argument #2 must be of type array, string given - --- Iteration 17 -- -array_diff_assoc(): Argument #2 must be of type array, string given - --- Iteration 18 -- -array_diff_assoc(): Argument #2 must be of type array, string given - --- Iteration 19 -- -array_diff_assoc(): Argument #2 must be of type array, string given - --- Iteration 20 -- -array_diff_assoc(): Argument #2 must be of type array, string given - --- Iteration 21 -- -array_diff_assoc(): Argument #2 must be of type array, string given - --- Iteration 22 -- -array_diff_assoc(): Argument #2 must be of type array, string given - --- Iteration 23 -- -array_diff_assoc(): Argument #2 must be of type array, classA given - --- Iteration 24 -- -array_diff_assoc(): Argument #2 must be of type array, null given - --- Iteration 25 -- -array_diff_assoc(): Argument #2 must be of type array, null given - --- Iteration 26 -- -array_diff_assoc(): Argument #2 must be of type array, resource given -Done diff --git a/ext/standard/tests/array/array_diff_assoc_variation3.phpt b/ext/standard/tests/array/array_diff_assoc_variation3.phpt index b32e484fd19..4833725ffe4 100644 --- a/ext/standard/tests/array/array_diff_assoc_variation3.phpt +++ b/ext/standard/tests/array/array_diff_assoc_variation3.phpt @@ -10,10 +10,6 @@ echo "\n*** Testing array_diff_assoc() : usage variations ***\n"; $array = array(1, 2, 3); -//get an unset variable -$unset_var = 10; -unset ($unset_var); - // get a class class classA { @@ -22,11 +18,6 @@ class classA } } -// heredoc string -$heredoc = << array( - NULL, null), // boolean data /*4*/ 'bool' => array( true, - false, - TRUE, - FALSE), + false), // empty data /*5*/ 'empty' => array( - "", ''), // string data /*6*/ 'string' => array( - "string", - 'string', - $heredoc), - - // binary data -/*7*/ -'binary' => array( - b"binary", - (binary)"binary"), + 'string'), // object data /*8*/ 'object' => array( new classA()), - - // undefined data -/*9*/ -'undefined' => array( - @$undefined_var), - - // unset data -/*10*/ -'unset' => array( - @$unset_var), ); // loop through each element of $inputs to check the behavior of array_diff_assoc @@ -135,65 +104,33 @@ array(5) { } -- Iteration 3 -- -array(2) { +array(1) { [0]=> NULL - [1]=> - NULL } -- Iteration 4 -- -array(3) { +array(1) { [1]=> bool(false) - [2]=> - bool(true) - [3]=> - bool(false) } -- Iteration 5 -- -array(2) { +array(1) { [0]=> string(0) "" - [1]=> - string(0) "" } -- Iteration 6 -- -array(3) { +array(1) { [0]=> string(6) "string" - [1]=> - string(6) "string" - [2]=> - string(11) "hello world" } -- Iteration 7 -- -array(2) { - [0]=> - string(6) "binary" - [1]=> - string(6) "binary" -} - --- Iteration 8 -- array(1) { [0]=> object(classA)#%d (0) { } } - --- Iteration 9 -- -array(1) { - [0]=> - NULL -} - --- Iteration 10 -- -array(1) { - [0]=> - NULL -} Done diff --git a/ext/standard/tests/array/array_diff_assoc_variation4.phpt b/ext/standard/tests/array/array_diff_assoc_variation4.phpt index 65b76dd9ebf..794a367368e 100644 --- a/ext/standard/tests/array/array_diff_assoc_variation4.phpt +++ b/ext/standard/tests/array/array_diff_assoc_variation4.phpt @@ -11,15 +11,6 @@ echo "\n*** Testing array_diff_assoc() : usage variations ***\n"; $array = array(1, 2, 3); -//get an unset variable -$unset_var = 10; -unset ($unset_var); - -// heredoc string -$heredoc = << 'positive', -2345 => 'negative'), - // null data -/*3*/ -'null' => array( - NULL => 'null 1', - null => 'null 2'), - - // boolean data -/*4*/ -'bool' => array( - true => 'boolt', - false => 'boolf', - TRUE => 'boolT', - FALSE => 'boolF'), - // empty data /*5*/ 'empty' => array( - "" => 'emptyd', - '' => 'emptys'), + '' => 'empty'), // string data /*6*/ 'string' => array( - "string" => 'stringd', - 'string' => 'strings', - $heredoc => 'stringh'), - - // binary data -/*7*/ -'binary' => array( - b"binary1" => 'binary 1', - (binary)"binary2" => 'binary 2'), - - // undefined data -/*8*/ -'undefined' => array( - @$undefined_var => 'undefined'), - - // unset data -/*9*/ -'unset' => array( - @$unset_var => 'unset'), + 'string' => 'strings'), ); @@ -104,48 +62,12 @@ array(4) { -- Iteration 2 -- array(1) { [""]=> - string(6) "null 2" + string(5) "empty" } -- Iteration 3 -- -array(2) { - [1]=> - string(5) "boolT" - [0]=> - string(5) "boolF" -} - --- Iteration 4 -- array(1) { - [""]=> - string(6) "emptys" -} - --- Iteration 5 -- -array(2) { ["string"]=> string(7) "strings" - ["hello world"]=> - string(7) "stringh" -} - --- Iteration 6 -- -array(2) { - ["binary1"]=> - string(8) "binary 1" - ["binary2"]=> - string(8) "binary 2" -} - --- Iteration 7 -- -array(1) { - [""]=> - string(9) "undefined" -} - --- Iteration 8 -- -array(1) { - [""]=> - string(5) "unset" } Done diff --git a/ext/standard/tests/array/array_diff_variation1.phpt b/ext/standard/tests/array/array_diff_variation1.phpt deleted file mode 100644 index 1031b6f947e..00000000000 --- a/ext/standard/tests/array/array_diff_variation1.phpt +++ /dev/null @@ -1,154 +0,0 @@ ---TEST-- -Test array_diff() function : usage variations - unexpected values for 'array1' argument ---FILE-- -getMessage(), "\n"; - } - $iterator++; -}; - -fclose($fp); -echo "Done"; -?> ---EXPECT-- -*** Testing array_diff() : usage variations *** - --- Iteration 1 --array_diff(): Argument #1 ($array) must be of type array, int given - --- Iteration 2 --array_diff(): Argument #1 ($array) must be of type array, int given - --- Iteration 3 --array_diff(): Argument #1 ($array) must be of type array, int given - --- Iteration 4 --array_diff(): Argument #1 ($array) must be of type array, int given - --- Iteration 5 --array_diff(): Argument #1 ($array) must be of type array, float given - --- Iteration 6 --array_diff(): Argument #1 ($array) must be of type array, float given - --- Iteration 7 --array_diff(): Argument #1 ($array) must be of type array, float given - --- Iteration 8 --array_diff(): Argument #1 ($array) must be of type array, float given - --- Iteration 9 --array_diff(): Argument #1 ($array) must be of type array, float given - --- Iteration 10 --array_diff(): Argument #1 ($array) must be of type array, null given - --- Iteration 11 --array_diff(): Argument #1 ($array) must be of type array, null given - --- Iteration 12 --array_diff(): Argument #1 ($array) must be of type array, true given - --- Iteration 13 --array_diff(): Argument #1 ($array) must be of type array, false given - --- Iteration 14 --array_diff(): Argument #1 ($array) must be of type array, true given - --- Iteration 15 --array_diff(): Argument #1 ($array) must be of type array, false given - --- Iteration 16 --array_diff(): Argument #1 ($array) must be of type array, string given - --- Iteration 17 --array_diff(): Argument #1 ($array) must be of type array, string given - --- Iteration 18 --array_diff(): Argument #1 ($array) must be of type array, string given - --- Iteration 19 --array_diff(): Argument #1 ($array) must be of type array, string given - --- Iteration 20 --array_diff(): Argument #1 ($array) must be of type array, string given - --- Iteration 21 --array_diff(): Argument #1 ($array) must be of type array, string given - --- Iteration 22 --array_diff(): Argument #1 ($array) must be of type array, string given - --- Iteration 23 --array_diff(): Argument #1 ($array) must be of type array, classA given - --- Iteration 24 --array_diff(): Argument #1 ($array) must be of type array, null given - --- Iteration 25 --array_diff(): Argument #1 ($array) must be of type array, null given - --- Iteration 26 --array_diff(): Argument #1 ($array) must be of type array, resource given -Done diff --git a/ext/standard/tests/array/array_diff_variation2.phpt b/ext/standard/tests/array/array_diff_variation2.phpt deleted file mode 100644 index 2b03f225136..00000000000 --- a/ext/standard/tests/array/array_diff_variation2.phpt +++ /dev/null @@ -1,153 +0,0 @@ ---TEST-- -Test array_diff() function : usage variations - unexpected values for 'array2' argument ---FILE-- -getMessage(), "\n"; - } - $iterator++; -}; -fclose($fp); -echo "Done"; -?> ---EXPECT-- -*** Testing array_diff() : usage variations *** - --- Iteration 1 --array_diff(): Argument #2 must be of type array, int given - --- Iteration 2 --array_diff(): Argument #2 must be of type array, int given - --- Iteration 3 --array_diff(): Argument #2 must be of type array, int given - --- Iteration 4 --array_diff(): Argument #2 must be of type array, int given - --- Iteration 5 --array_diff(): Argument #2 must be of type array, float given - --- Iteration 6 --array_diff(): Argument #2 must be of type array, float given - --- Iteration 7 --array_diff(): Argument #2 must be of type array, float given - --- Iteration 8 --array_diff(): Argument #2 must be of type array, float given - --- Iteration 9 --array_diff(): Argument #2 must be of type array, float given - --- Iteration 10 --array_diff(): Argument #2 must be of type array, null given - --- Iteration 11 --array_diff(): Argument #2 must be of type array, null given - --- Iteration 12 --array_diff(): Argument #2 must be of type array, true given - --- Iteration 13 --array_diff(): Argument #2 must be of type array, false given - --- Iteration 14 --array_diff(): Argument #2 must be of type array, true given - --- Iteration 15 --array_diff(): Argument #2 must be of type array, false given - --- Iteration 16 --array_diff(): Argument #2 must be of type array, string given - --- Iteration 17 --array_diff(): Argument #2 must be of type array, string given - --- Iteration 18 --array_diff(): Argument #2 must be of type array, string given - --- Iteration 19 --array_diff(): Argument #2 must be of type array, string given - --- Iteration 20 --array_diff(): Argument #2 must be of type array, string given - --- Iteration 21 --array_diff(): Argument #2 must be of type array, string given - --- Iteration 22 --array_diff(): Argument #2 must be of type array, string given - --- Iteration 23 --array_diff(): Argument #2 must be of type array, classA given - --- Iteration 24 --array_diff(): Argument #2 must be of type array, null given - --- Iteration 25 --array_diff(): Argument #2 must be of type array, null given - --- Iteration 26 --array_diff(): Argument #2 must be of type array, resource given -Done diff --git a/ext/standard/tests/array/array_diff_variation3.phpt b/ext/standard/tests/array/array_diff_variation3.phpt index 37b295b0bd6..649dcb5c92a 100644 --- a/ext/standard/tests/array/array_diff_variation3.phpt +++ b/ext/standard/tests/array/array_diff_variation3.phpt @@ -12,15 +12,6 @@ echo "*** Testing array_diff() : usage variations ***\n"; // Initialise function arguments not being substituted (if any) $array = array(1, 2); -//get an unset variable -$unset_var = 10; -unset ($unset_var); - -//get heredoc -$heredoc = << array( // null data - NULL, null), /*5*/ "boolean" => array( // boolean data true, - false, - TRUE, - FALSE), + false), /*6*/ -"empty" => array( - // empty data - "", - ''), +"empty" => array(''), /*7*/ -"string" => array( - // string data - "string", - 'string', - $heredoc), - -/*8*/ -"binary" => array( - // binary data - b"binary", - (binary)"binary"), - -/*9*/ -"undefined" => array( - // undefined data - @$undefined_var), - -/*10*/ -"unset" => array( - // unset data - @$unset_var) +"string" => array('string'), ); // loop through each element of the array for arr1 $iterator = 1; foreach($values as $value) { - echo "\n Iteration: $iterator \n"; + echo "Iteration: $iterator\n"; var_dump( array_diff($value, $array) ); $iterator++; }; @@ -99,12 +64,10 @@ echo "Done"; ?> --EXPECT-- *** Testing array_diff() : usage variations *** - - Iteration: 1 +Iteration: 1 array(0) { } - - Iteration: 2 +Iteration: 2 array(3) { [0]=> int(0) @@ -113,8 +76,7 @@ array(3) { [3]=> int(-2345) } - - Iteration: 3 +Iteration: 3 array(5) { [0]=> float(10.5) @@ -127,58 +89,24 @@ array(5) { [4]=> float(0.5) } - - Iteration: 4 -array(2) { - [0]=> - NULL - [1]=> - NULL -} - - Iteration: 5 -array(2) { - [1]=> - bool(false) - [3]=> - bool(false) -} - - Iteration: 6 -array(2) { - [0]=> - string(0) "" - [1]=> - string(0) "" -} - - Iteration: 7 -array(3) { - [0]=> - string(6) "string" - [1]=> - string(6) "string" - [2]=> - string(17) "This is a heredoc" -} - - Iteration: 8 -array(2) { - [0]=> - string(6) "binary" - [1]=> - string(6) "binary" -} - - Iteration: 9 +Iteration: 4 array(1) { [0]=> NULL } - - Iteration: 10 +Iteration: 5 +array(1) { + [1]=> + bool(false) +} +Iteration: 6 array(1) { [0]=> - NULL + string(0) "" +} +Iteration: 7 +array(1) { + [0]=> + string(6) "string" } Done diff --git a/ext/standard/tests/array/array_diff_variation4.phpt b/ext/standard/tests/array/array_diff_variation4.phpt index 090f162bc7d..301280bcea5 100644 --- a/ext/standard/tests/array/array_diff_variation4.phpt +++ b/ext/standard/tests/array/array_diff_variation4.phpt @@ -12,15 +12,6 @@ echo "*** Testing array_diff() : usage variations ***\n"; // Initialise function arguments not being substituted (if any) $array = array(1, 2); -//get an unset variable -$unset_var = 10; -unset ($unset_var); - -//get heredoc -$heredoc = << array( // null data - NULL, null), /*5*/ "boolean" => array( // boolean data true, - false, - TRUE, - FALSE), + false), /*6*/ "empty" => array( // empty data - "", ''), /*7*/ "string" => array( // string data - "string", - 'string', - $heredoc), - -/*8*/ -"binary" => array( - // binary data - b"binary", - (binary)"binary"), - -/*9*/ -"undefined" => array( - // undefined data - @$undefined_var), - -/*10*/ -"unset" => array( - // unset data - @$unset_var) + 'string'), ); // loop through each element of the array for $arr2 @@ -151,28 +120,4 @@ array(2) { [1]=> int(2) } - - Iteration: 8 -array(2) { - [0]=> - int(1) - [1]=> - int(2) -} - - Iteration: 9 -array(2) { - [0]=> - int(1) - [1]=> - int(2) -} - - Iteration: 10 -array(2) { - [0]=> - int(1) - [1]=> - int(2) -} Done diff --git a/ext/standard/tests/array/array_filter_variation9.phpt b/ext/standard/tests/array/array_filter_variation9.phpt index ff0dc771171..2e6efc0eda5 100644 --- a/ext/standard/tests/array/array_filter_variation9.phpt +++ b/ext/standard/tests/array/array_filter_variation9.phpt @@ -8,7 +8,7 @@ Test array_filter() function : usage variations - built-in functions as 'callbac echo "*** Testing array_filter() : usage variations - built-in functions as 'callback' argument ***\n"; -$input = array(0, 1, -1, 10, 100, 1000); +$input = array(0, 1, 10, 100); // using built-in function 'is_int' as 'callback' var_dump( array_filter($input, 'is_int') ); @@ -34,33 +34,25 @@ echo "Done" ?> --EXPECT-- *** Testing array_filter() : usage variations - built-in functions as 'callback' argument *** -array(6) { +array(4) { [0]=> int(0) [1]=> int(1) [2]=> - int(-1) - [3]=> int(10) - [4]=> + [3]=> int(100) - [5]=> - int(1000) } -array(6) { +array(4) { [0]=> int(0) [1]=> int(1) [2]=> - int(-1) - [3]=> int(10) - [4]=> + [3]=> int(100) - [5]=> - int(1000) } array_filter(): Argument #2 ($callback) must be a valid callback or null, function "echo" not found or invalid function name array_filter(): Argument #2 ($callback) must be a valid callback or null, function "isset" not found or invalid function name diff --git a/ext/standard/tests/array/gh16649/array_splice_normal_destructor.phpt b/ext/standard/tests/array/gh16649/array_splice_normal_destructor.phpt new file mode 100644 index 00000000000..59c0b316f54 --- /dev/null +++ b/ext/standard/tests/array/gh16649/array_splice_normal_destructor.phpt @@ -0,0 +1,20 @@ +--TEST-- +GH-16649: array_splice with normal destructor should work fine +--FILE-- + +--EXPECT-- +Destructor called +array(1) { + [0]=> + string(1) "1" +} diff --git a/ext/standard/tests/array/gh16649/array_splice_uaf_add_elements.phpt b/ext/standard/tests/array/gh16649/array_splice_uaf_add_elements.phpt new file mode 100644 index 00000000000..f5e538122f4 --- /dev/null +++ b/ext/standard/tests/array/gh16649/array_splice_uaf_add_elements.phpt @@ -0,0 +1,22 @@ +--TEST-- +GH-16649: array_splice UAF when destructor adds elements to array +--FILE-- +getMessage() . "\n"; +} +?> +--EXPECT-- +Exception caught: Array was modified during array_splice operation diff --git a/ext/standard/tests/array/gh16649/array_splice_uaf_array_deallocated.phpt b/ext/standard/tests/array/gh16649/array_splice_uaf_array_deallocated.phpt new file mode 100644 index 00000000000..1874ddad893 --- /dev/null +++ b/ext/standard/tests/array/gh16649/array_splice_uaf_array_deallocated.phpt @@ -0,0 +1,22 @@ +--TEST-- +GH-16649: array_splice UAF when array is released entirely +--FILE-- +getMessage() . "\n"; +} +?> +--EXPECT-- +Exception caught: Array was modified during array_splice operation diff --git a/ext/standard/tests/array/gh16649/array_splice_uaf_complex_modification.phpt b/ext/standard/tests/array/gh16649/array_splice_uaf_complex_modification.phpt new file mode 100644 index 00000000000..8ad4133300e --- /dev/null +++ b/ext/standard/tests/array/gh16649/array_splice_uaf_complex_modification.phpt @@ -0,0 +1,25 @@ +--TEST-- +GH-16649: array_splice UAF with complex array modification +--FILE-- +getMessage() . "\n"; +} +?> +--EXPECT-- +Exception caught: Array was modified during array_splice operation diff --git a/ext/standard/tests/array/gh16649/array_splice_uaf_multiple_destructors.phpt b/ext/standard/tests/array/gh16649/array_splice_uaf_multiple_destructors.phpt new file mode 100644 index 00000000000..9e2c6cf8fc7 --- /dev/null +++ b/ext/standard/tests/array/gh16649/array_splice_uaf_multiple_destructors.phpt @@ -0,0 +1,33 @@ +--TEST-- +GH-16649: array_splice UAF with multiple destructors +--FILE-- +id = $id; + } + + function __destruct() { + global $arr; + echo "Destructor {$this->id} called\n"; + if ($this->id == 2) { + $arr = null; + } + } +} + +$arr = ["start", new MultiDestructor(1), new MultiDestructor(2), "end"]; + +try { + array_splice($arr, 1, 2); + echo "ERROR: Should have thrown exception\n"; +} catch (Error $e) { + echo "Exception caught: " . $e->getMessage() . "\n"; +} +?> +--EXPECT-- +Destructor 1 called +Destructor 2 called +Exception caught: Array was modified during array_splice operation diff --git a/ext/standard/tests/array/gh16649/array_splice_uaf_original_case.phpt b/ext/standard/tests/array/gh16649/array_splice_uaf_original_case.phpt new file mode 100644 index 00000000000..4a82d589315 --- /dev/null +++ b/ext/standard/tests/array/gh16649/array_splice_uaf_original_case.phpt @@ -0,0 +1,29 @@ +--TEST-- +GH-16649: array_splice UAF with destructor modifying array (original case) +--FILE-- + "1", "3" => new C, "2" => "2"]; + +try { + array_splice($arr, 1, 2); + echo "ERROR: Should have thrown exception\n"; +} catch (Error $e) { + echo "Exception caught: " . $e->getMessage() . "\n"; +} +?> +--EXPECT-- +Exception caught: Array was modified during array_splice operation diff --git a/ext/standard/tests/array/gh16649/array_splice_uaf_packed_to_hash.phpt b/ext/standard/tests/array/gh16649/array_splice_uaf_packed_to_hash.phpt new file mode 100644 index 00000000000..bd8f511b625 --- /dev/null +++ b/ext/standard/tests/array/gh16649/array_splice_uaf_packed_to_hash.phpt @@ -0,0 +1,23 @@ +--TEST-- +GH-16649: array_splice UAF when array is converted from packed to hash +--FILE-- +getMessage() . "\n"; +} +?> +--EXPECT-- +Exception caught: Array was modified during array_splice operation diff --git a/ext/standard/tests/array/gh16649/array_splice_with_replacement.phpt b/ext/standard/tests/array/gh16649/array_splice_with_replacement.phpt new file mode 100644 index 00000000000..8754a913a24 --- /dev/null +++ b/ext/standard/tests/array/gh16649/array_splice_with_replacement.phpt @@ -0,0 +1,23 @@ +--TEST-- +GH-16649: array_splice with replacement array when destructor modifies array +--FILE-- +getMessage() . "\n"; +} +?> +--EXPECT-- +Exception caught: Array was modified during array_splice operation diff --git a/ext/standard/tests/array/gh19300_1.phpt b/ext/standard/tests/array/gh19300_1.phpt new file mode 100644 index 00000000000..18b639bf425 --- /dev/null +++ b/ext/standard/tests/array/gh19300_1.phpt @@ -0,0 +1,40 @@ +--TEST-- +GH-19300 (Nested array_multisort invocation with error breaks) - correct invocation variation +--FILE-- +data; + } +} + +$inputs = [ + new MyStringable('3'), + new MyStringable('1'), + new MyStringable('2'), +]; + +var_dump(array_multisort($inputs, SORT_STRING)); +var_dump($inputs); +?> +--EXPECT-- +bool(true) +array(3) { + [0]=> + object(MyStringable)#2 (1) { + ["data":"MyStringable":private]=> + string(1) "1" + } + [1]=> + object(MyStringable)#3 (1) { + ["data":"MyStringable":private]=> + string(1) "2" + } + [2]=> + object(MyStringable)#1 (1) { + ["data":"MyStringable":private]=> + string(1) "3" + } +} diff --git a/ext/standard/tests/array/gh19300_2.phpt b/ext/standard/tests/array/gh19300_2.phpt new file mode 100644 index 00000000000..41ae7e82bb7 --- /dev/null +++ b/ext/standard/tests/array/gh19300_2.phpt @@ -0,0 +1,40 @@ +--TEST-- +GH-19300 (Nested array_multisort invocation with error breaks) - error variation +--FILE-- +getMessage(), "\n"; + } +} +set_error_handler('error_handle'); + +$inputs = [ + new stdClass, + new stdClass, + new stdClass, +]; + +var_dump(array_multisort($inputs, SORT_NUMERIC)); +var_dump($inputs); +?> +--EXPECT-- +array_multisort(): Argument #1 ($array) must be an array or a sort flag +array_multisort(): Argument #1 ($array) must be an array or a sort flag +array_multisort(): Argument #1 ($array) must be an array or a sort flag +array_multisort(): Argument #1 ($array) must be an array or a sort flag +bool(true) +array(3) { + [0]=> + object(stdClass)#1 (0) { + } + [1]=> + object(stdClass)#2 (0) { + } + [2]=> + object(stdClass)#3 (0) { + } +} diff --git a/ext/standard/tests/class_object/get_object_vars_variation_005.phpt b/ext/standard/tests/class_object/get_object_vars_variation_005.phpt index 1ad1bb39332..2fed6468c53 100644 --- a/ext/standard/tests/class_object/get_object_vars_variation_005.phpt +++ b/ext/standard/tests/class_object/get_object_vars_variation_005.phpt @@ -25,6 +25,7 @@ var_dump(get_object_vars($obj)); ?> --EXPECTF-- +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d array(3) { ["%0A%0b"]=> int(42) @@ -33,6 +34,8 @@ array(3) { [12]=> int(6) } + +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d array(4) { ["prop"]=> NULL diff --git a/ext/standard/tests/dir/bug73877.phpt b/ext/standard/tests/dir/bug73877.phpt index ceb272ea652..e538bed0d89 100644 --- a/ext/standard/tests/dir/bug73877.phpt +++ b/ext/standard/tests/dir/bug73877.phpt @@ -18,7 +18,7 @@ $junk0 = $base . DIRECTORY_SEPARATOR . "Серёжка2"; mkdir($base); mkdir($dir0); mkdir($dir1); -`mklink /J $junk0 $dir0`; +shell_exec("mklink /J $junk0 $dir0"); var_dump( readlink($dir0), diff --git a/ext/standard/tests/dir/closedir_basic-win32-mb.phpt b/ext/standard/tests/dir/closedir_basic-win32-mb.phpt index 05cb1889c94..3754963a850 100644 --- a/ext/standard/tests/dir/closedir_basic-win32-mb.phpt +++ b/ext/standard/tests/dir/closedir_basic-win32-mb.phpt @@ -44,6 +44,8 @@ rmdir($dir_path); *** Testing closedir() : basic functionality *** -- Call closedir() with no arguments: -- + +Deprecated: closedir(): Passing null is deprecated, instead the last opened directory stream should be provided in %s on line %d NULL -- Check Directory Handle: -- resource(%d) of type (Unknown) diff --git a/ext/standard/tests/dir/closedir_basic.phpt b/ext/standard/tests/dir/closedir_basic.phpt index aa4be6fbaf2..82065f01419 100644 --- a/ext/standard/tests/dir/closedir_basic.phpt +++ b/ext/standard/tests/dir/closedir_basic.phpt @@ -38,6 +38,8 @@ rmdir($dir_path); *** Testing closedir() : basic functionality *** -- Call closedir() with no arguments: -- + +Deprecated: closedir(): Passing null is deprecated, instead the last opened directory stream should be provided in %s on line %d NULL -- Check Directory Handle: -- resource(%d) of type (Unknown) diff --git a/ext/standard/tests/dir/closedir_without_arg.phpt b/ext/standard/tests/dir/closedir_without_arg.phpt index 27884c1a2b6..f248764ed2a 100644 --- a/ext/standard/tests/dir/closedir_without_arg.phpt +++ b/ext/standard/tests/dir/closedir_without_arg.phpt @@ -8,5 +8,6 @@ try { echo $e->getMessage(), "\n"; } ?> ---EXPECT-- +--EXPECTF-- +Deprecated: closedir(): Passing null is deprecated, instead the last opened directory stream should be provided in %s on line %d No resource supplied diff --git a/ext/standard/tests/dir/readdir_basic-win32-mb.phpt b/ext/standard/tests/dir/readdir_basic-win32-mb.phpt index d7e0804d57b..dd97566db07 100644 --- a/ext/standard/tests/dir/readdir_basic-win32-mb.phpt +++ b/ext/standard/tests/dir/readdir_basic-win32-mb.phpt @@ -65,6 +65,18 @@ string(9) "file3.tmp" -- Call readdir() without $path argument -- resource(%d) of type (stream) + +Deprecated: readdir(): Passing null is deprecated, instead the last opened directory stream should be provided in %s on line %d + +Deprecated: readdir(): Passing null is deprecated, instead the last opened directory stream should be provided in %s on line %d + +Deprecated: readdir(): Passing null is deprecated, instead the last opened directory stream should be provided in %s on line %d + +Deprecated: readdir(): Passing null is deprecated, instead the last opened directory stream should be provided in %s on line %d + +Deprecated: readdir(): Passing null is deprecated, instead the last opened directory stream should be provided in %s on line %d + +Deprecated: readdir(): Passing null is deprecated, instead the last opened directory stream should be provided in %s on line %d string(1) "." string(2) ".." string(9) "file1.tmp" diff --git a/ext/standard/tests/dir/readdir_basic.phpt b/ext/standard/tests/dir/readdir_basic.phpt index 01ddd694adc..fbabfc6e9b2 100644 --- a/ext/standard/tests/dir/readdir_basic.phpt +++ b/ext/standard/tests/dir/readdir_basic.phpt @@ -59,6 +59,18 @@ string(9) "file3.tmp" -- Call readdir() without $path argument -- resource(%d) of type (stream) + +Deprecated: readdir(): Passing null is deprecated, instead the last opened directory stream should be provided in %s on line %d + +Deprecated: readdir(): Passing null is deprecated, instead the last opened directory stream should be provided in %s on line %d + +Deprecated: readdir(): Passing null is deprecated, instead the last opened directory stream should be provided in %s on line %d + +Deprecated: readdir(): Passing null is deprecated, instead the last opened directory stream should be provided in %s on line %d + +Deprecated: readdir(): Passing null is deprecated, instead the last opened directory stream should be provided in %s on line %d + +Deprecated: readdir(): Passing null is deprecated, instead the last opened directory stream should be provided in %s on line %d string(1) "." string(2) ".." string(9) "file1.tmp" diff --git a/ext/standard/tests/dir/readdir_variation6-win32-mb.phpt b/ext/standard/tests/dir/readdir_variation6-win32-mb.phpt index 91062e76bd4..c2bfe7d1a2b 100644 --- a/ext/standard/tests/dir/readdir_variation6-win32-mb.phpt +++ b/ext/standard/tests/dir/readdir_variation6-win32-mb.phpt @@ -61,7 +61,7 @@ closedir(); $dir_path = __DIR__ . "/私はガラスを食べられますreaddir_variation6"; rmdir($dir_path); ?> ---EXPECT-- +--EXPECTF-- *** Testing readdir() : usage variations *** -- Reading Directory Contents with Previous Handle -- @@ -72,8 +72,22 @@ string(59) "私はガラスを食べられますreaddir_variation62.tmp" string(59) "私はガラスを食べられますreaddir_variation63.tmp" -- Reading Directory Contents with Current Handle (no arguments supplied) -- + +Deprecated: readdir(): Passing null is deprecated, instead the last opened directory stream should be provided in %s on line %d + +Deprecated: readdir(): Passing null is deprecated, instead the last opened directory stream should be provided in %s on line %d + +Deprecated: readdir(): Passing null is deprecated, instead the last opened directory stream should be provided in %s on line %d + +Deprecated: readdir(): Passing null is deprecated, instead the last opened directory stream should be provided in %s on line %d + +Deprecated: readdir(): Passing null is deprecated, instead the last opened directory stream should be provided in %s on line %d + +Deprecated: readdir(): Passing null is deprecated, instead the last opened directory stream should be provided in %s on line %d string(1) "." string(2) ".." string(59) "私はガラスを食べられますreaddir_variation61.tmp" string(59) "私はガラスを食べられますreaddir_variation62.tmp" string(59) "私はガラスを食べられますreaddir_variation63.tmp" + +Deprecated: closedir(): Passing null is deprecated, instead the last opened directory stream should be provided in %s on line %d diff --git a/ext/standard/tests/dir/readdir_variation6.phpt b/ext/standard/tests/dir/readdir_variation6.phpt index b017789f31a..9865a1d4fc6 100644 --- a/ext/standard/tests/dir/readdir_variation6.phpt +++ b/ext/standard/tests/dir/readdir_variation6.phpt @@ -55,7 +55,7 @@ closedir(); $dir_path = __DIR__ . "/readdir_variation6"; rmdir($dir_path); ?> ---EXPECT-- +--EXPECTF-- *** Testing readdir() : usage variations *** -- Reading Directory Contents with Previous Handle -- @@ -66,8 +66,22 @@ string(23) "readdir_variation62.tmp" string(23) "readdir_variation63.tmp" -- Reading Directory Contents with Current Handle (no arguments supplied) -- + +Deprecated: readdir(): Passing null is deprecated, instead the last opened directory stream should be provided in %s on line %d + +Deprecated: readdir(): Passing null is deprecated, instead the last opened directory stream should be provided in %s on line %d + +Deprecated: readdir(): Passing null is deprecated, instead the last opened directory stream should be provided in %s on line %d + +Deprecated: readdir(): Passing null is deprecated, instead the last opened directory stream should be provided in %s on line %d + +Deprecated: readdir(): Passing null is deprecated, instead the last opened directory stream should be provided in %s on line %d + +Deprecated: readdir(): Passing null is deprecated, instead the last opened directory stream should be provided in %s on line %d string(1) "." string(2) ".." string(23) "readdir_variation61.tmp" string(23) "readdir_variation62.tmp" string(23) "readdir_variation63.tmp" + +Deprecated: closedir(): Passing null is deprecated, instead the last opened directory stream should be provided in %s on line %d diff --git a/ext/standard/tests/dir/rewinddir_basic-win32-mb.phpt b/ext/standard/tests/dir/rewinddir_basic-win32-mb.phpt index a20501d3cad..2ec56418c85 100644 --- a/ext/standard/tests/dir/rewinddir_basic-win32-mb.phpt +++ b/ext/standard/tests/dir/rewinddir_basic-win32-mb.phpt @@ -82,6 +82,14 @@ NULL bool(true) -- Read and rewind second directory (no argument supplied) -- + +Deprecated: readdir(): Passing null is deprecated, instead the last opened directory stream should be provided in %s on line %d + +Deprecated: readdir(): Passing null is deprecated, instead the last opened directory stream should be provided in %s on line %d + +Deprecated: readdir(): Passing null is deprecated, instead the last opened directory stream should be provided in %s on line %d + +Deprecated: readdir(): Passing null is deprecated, instead the last opened directory stream should be provided in %s on line %d array(3) { [0]=> string(1) "." @@ -90,5 +98,9 @@ array(3) { [2]=> string(45) "私はガラスを食べられますfile2.tmp" } + +Deprecated: rewinddir(): Passing null is deprecated, instead the last opened directory stream should be provided in %s on line %d NULL + +Deprecated: readdir(): Passing null is deprecated, instead the last opened directory stream should be provided in %s on line %d bool(true) diff --git a/ext/standard/tests/dir/rewinddir_basic.phpt b/ext/standard/tests/dir/rewinddir_basic.phpt index faee6b9bd64..106c00051d6 100644 --- a/ext/standard/tests/dir/rewinddir_basic.phpt +++ b/ext/standard/tests/dir/rewinddir_basic.phpt @@ -76,6 +76,14 @@ NULL bool(true) -- Read and rewind second directory (no argument supplied) -- + +Deprecated: readdir(): Passing null is deprecated, instead the last opened directory stream should be provided in %s on line %d + +Deprecated: readdir(): Passing null is deprecated, instead the last opened directory stream should be provided in %s on line %d + +Deprecated: readdir(): Passing null is deprecated, instead the last opened directory stream should be provided in %s on line %d + +Deprecated: readdir(): Passing null is deprecated, instead the last opened directory stream should be provided in %s on line %d array(3) { [0]=> string(1) "." @@ -84,5 +92,9 @@ array(3) { [2]=> string(9) "file2.tmp" } + +Deprecated: rewinddir(): Passing null is deprecated, instead the last opened directory stream should be provided in %s on line %d NULL + +Deprecated: readdir(): Passing null is deprecated, instead the last opened directory stream should be provided in %s on line %d bool(true) diff --git a/ext/standard/tests/directory/DirectoryClass_readonly_handle_by_pass_via_ArrayObject.phpt b/ext/standard/tests/directory/DirectoryClass_readonly_handle_by_pass_via_ArrayObject.phpt index 91416f2c712..5af789ff424 100644 --- a/ext/standard/tests/directory/DirectoryClass_readonly_handle_by_pass_via_ArrayObject.phpt +++ b/ext/standard/tests/directory/DirectoryClass_readonly_handle_by_pass_via_ArrayObject.phpt @@ -28,7 +28,8 @@ try { } ?> ---EXPECT-- +--EXPECTF-- +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d resource(3) of type (stream) Error: Internal directory stream has been altered Error: Typed property Directory::$handle must not be accessed before initialization diff --git a/ext/standard/tests/file/bug81145.phpt b/ext/standard/tests/file/bug81145.phpt index f3258ff6019..27026176193 100644 --- a/ext/standard/tests/file/bug81145.phpt +++ b/ext/standard/tests/file/bug81145.phpt @@ -9,8 +9,8 @@ if (PHP_OS_FAMILY !== "Windows") { $src = __DIR__ . "/bug81145_src.bin"; define('SIZE_4G', 0x100000000); exec("fallocate -l " . (SIZE_4G-0x100) . " " . escapeshellarg($src), $output, $status); - if ($status !== 0) die("skip fallocate() not supported"); @unlink(__DIR__ . "/bug81145_src.bin"); + if ($status !== 0) die("skip fallocate() not supported"); } ?> --CONFLICTS-- diff --git a/ext/standard/tests/file/chmod_variation2.phpt b/ext/standard/tests/file/chmod_variation2.phpt index e96af25ec46..c2b6c2e810a 100644 --- a/ext/standard/tests/file/chmod_variation2.phpt +++ b/ext/standard/tests/file/chmod_variation2.phpt @@ -34,7 +34,7 @@ clearstatcache(); printf("%o\n", fileperms($filepath) & PERMISSIONS_MASK); echo "\nchmod() on a linked file\n"; -$linkname = "somelink"; +$linkname = "somelink2"; var_dump(symlink($filepath, $linkname)); var_dump(chmod($filepath, 0777)); var_dump(chmod($linkname, 0755)); diff --git a/ext/standard/tests/file/file_variation5.phpt b/ext/standard/tests/file/file_variation5.phpt index d1c5e1498be..3db848cdbbf 100644 --- a/ext/standard/tests/file/file_variation5.phpt +++ b/ext/standard/tests/file/file_variation5.phpt @@ -27,7 +27,7 @@ echo "\nfile() on a path containing .. with invalid directories\n"; var_dump(file("./$test_dirname/bad_dir/../../$filename")); echo "\nfile() on a linked file\n"; -$linkname = "somelink"; +$linkname = "somelink5"; var_dump(symlink($filepath, $linkname)); var_dump(file($linkname)); var_dump(unlink($linkname)); diff --git a/ext/standard/tests/file/fread_socket_variation1.phpt b/ext/standard/tests/file/fread_socket_variation1.phpt index 09b3d65393a..62d4b33ba48 100644 --- a/ext/standard/tests/file/fread_socket_variation1.phpt +++ b/ext/standard/tests/file/fread_socket_variation1.phpt @@ -12,7 +12,7 @@ for ($i=0; $i<100; $i++) { } } -socket_set_timeout($server, 0, 1000); +stream_set_timeout($server, 0, 1000); var_dump(fread($server, 1)); diff --git a/ext/standard/tests/file/mkdir-002.phpt b/ext/standard/tests/file/mkdir-002.phpt index f4a42a7d619..d48b19e645b 100644 --- a/ext/standard/tests/file/mkdir-002.phpt +++ b/ext/standard/tests/file/mkdir-002.phpt @@ -11,13 +11,13 @@ if (substr(PHP_OS, 0, 3) == 'WIN') { var_dump(mkdir("mkdir-002", 0777)); var_dump(mkdir("mkdir-002/subdir", 0777)); -var_dump(`ls -l mkdir-002`); +var_dump(shell_exec("ls -l mkdir-002")); var_dump(rmdir("mkdir-002/subdir")); var_dump(rmdir("mkdir-002")); var_dump(mkdir("./mkdir-002", 0777)); var_dump(mkdir("./mkdir-002/subdir", 0777)); -var_dump(`ls -l ./mkdir-002`); +var_dump(shell_exec("ls -l ./mkdir-002")); var_dump(rmdir("./mkdir-002/subdir")); var_dump(rmdir("./mkdir-002")); @@ -25,7 +25,7 @@ var_dump(mkdir(__DIR__."/mkdir-002", 0777)); var_dump(mkdir(__DIR__."/mkdir-002/subdir", 0777)); $dirname = __DIR__."/mkdir-002"; $dirname_escaped = escapeshellarg($dirname); -var_dump(`ls -l $dirname_escaped`); +var_dump(shell_exec("ls -l $dirname_escaped")); var_dump(rmdir(__DIR__."/mkdir-002/subdir")); var_dump(rmdir(__DIR__."/mkdir-002")); diff --git a/ext/standard/tests/file/parse_ini_file_variation3.phpt b/ext/standard/tests/file/parse_ini_file_variation3.phpt index 29e620dc8da..8485e8d01ef 100644 --- a/ext/standard/tests/file/parse_ini_file_variation3.phpt +++ b/ext/standard/tests/file/parse_ini_file_variation3.phpt @@ -35,7 +35,6 @@ display_startup_errors = Off log_errors = Off ignore_repeated_errors = Off ignore_repeated_source = Off -report_memleaks = On docref_root = "/phpmanual/" docref_ext = .html @@ -68,7 +67,7 @@ foreach($newdirs as $newdir) { --EXPECTF-- *** Testing parse_ini_file() : variation *** New include path is : %sparse_ini_file_variation3.dir1%sparse_ini_file_variation3.dir2%sparse_ini_file_variation3.dir3%S -array(9) { +array(8) { ["error_reporting"]=> string(5) "30719" ["display_errors"]=> @@ -81,8 +80,6 @@ array(9) { string(0) "" ["ignore_repeated_source"]=> string(0) "" - ["report_memleaks"]=> - string(1) "1" ["docref_root"]=> string(11) "/phpmanual/" ["docref_ext"]=> diff --git a/ext/standard/tests/file/popen_pclose_basic-win32-mb.phpt b/ext/standard/tests/file/popen_pclose_basic-win32-mb.phpt index 7bb4c1be02c..b0a28055893 100644 --- a/ext/standard/tests/file/popen_pclose_basic-win32-mb.phpt +++ b/ext/standard/tests/file/popen_pclose_basic-win32-mb.phpt @@ -35,8 +35,8 @@ $sysroot = exec('echo %SYSTEMROOT%'); $file_handle = popen("$sysroot/system32/sort", "w"); $newline = "\n"; foreach($arr as $str) { - fwrite($file_handle, (binary)$str); - fwrite($file_handle, (binary)(binary)(binary)(binary)(binary)(binary)(binary)(binary)(binary)$newline); + fwrite($file_handle, $str); + fwrite($file_handle, $newline); } pclose($file_handle); diff --git a/ext/standard/tests/file/popen_pclose_basic-win32.phpt b/ext/standard/tests/file/popen_pclose_basic-win32.phpt index 61f2fa302bf..e5f155be329 100644 --- a/ext/standard/tests/file/popen_pclose_basic-win32.phpt +++ b/ext/standard/tests/file/popen_pclose_basic-win32.phpt @@ -35,8 +35,8 @@ $sysroot = exec('echo %SYSTEMROOT%'); $file_handle = popen("$sysroot/system32/sort", "w"); $newline = "\n"; foreach($arr as $str) { - fwrite($file_handle, (binary)$str); - fwrite($file_handle, (binary)(binary)(binary)(binary)(binary)(binary)(binary)(binary)(binary)$newline); + fwrite($file_handle, $str); + fwrite($file_handle, $newline); } pclose($file_handle); diff --git a/ext/standard/tests/file/userstreams_005.phpt b/ext/standard/tests/file/userstreams_005.phpt index 8d37040e195..11dc8d45b0c 100644 --- a/ext/standard/tests/file/userstreams_005.phpt +++ b/ext/standard/tests/file/userstreams_005.phpt @@ -65,5 +65,5 @@ ftruncate(): Argument #2 ($size) must be greater than or equal to 0 ------ stream_truncate bad return: ------- truncation with new_size=0 -Warning: ftruncate(): test_wrapper_bad::stream_truncate did not return a boolean! in %s on line %d +Warning: ftruncate(): test_wrapper_bad::stream_truncate value must be of type bool, string given in %s on line %d bool(false) diff --git a/ext/standard/tests/image/bug13213.phpt b/ext/standard/tests/image/bug13213.phpt index 61fe245efed..dd5821a8303 100644 --- a/ext/standard/tests/image/bug13213.phpt +++ b/ext/standard/tests/image/bug13213.phpt @@ -6,7 +6,7 @@ var_dump(GetImageSize(__DIR__.'/bug13213.jpg')); ?> --EXPECTF-- Warning: getimagesize(): Corrupt JPEG data: 2 extraneous bytes before marker in %s%ebug13213.php on line %d -array(7) { +array(9) { [0]=> int(1) [1]=> @@ -21,4 +21,8 @@ array(7) { int(3) ["mime"]=> string(10) "image/jpeg" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" } diff --git a/ext/standard/tests/image/bug70052.phpt b/ext/standard/tests/image/bug70052.phpt index 76ebda92b22..252f8921e29 100644 --- a/ext/standard/tests/image/bug70052.phpt +++ b/ext/standard/tests/image/bug70052.phpt @@ -7,7 +7,7 @@ var_dump(getimagesize(__DIR__ . '/bug70052_2.wbmp')); ?> --EXPECT-- bool(false) -array(5) { +array(7) { [0]=> int(3) [1]=> @@ -18,4 +18,8 @@ array(5) { string(20) "width="3" height="3"" ["mime"]=> string(18) "image/vnd.wap.wbmp" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" } diff --git a/ext/standard/tests/image/bug70096.phpt b/ext/standard/tests/image/bug70096.phpt index 53ceddea06a..757287d5aed 100644 --- a/ext/standard/tests/image/bug70096.phpt +++ b/ext/standard/tests/image/bug70096.phpt @@ -11,7 +11,6 @@ if (!function_exists('imagejpeg')) die('skip imagejpeg not available'); $filename = __DIR__ . '/bug70096.jpg'; $im = imagecreatetruecolor(10, 10); imagejpeg($im, $filename); -imagedestroy($im); $data = "\x1C\x02x\x00\x0ATest image" . "\x1C\x02t\x00\x22Copyright 2008-2009, The PHP Group"; $content1 = iptcembed($data, $filename); diff --git a/ext/standard/tests/image/bug71848.phpt b/ext/standard/tests/image/bug71848.phpt index 25c05689e6e..1c15c87011c 100644 --- a/ext/standard/tests/image/bug71848.phpt +++ b/ext/standard/tests/image/bug71848.phpt @@ -6,7 +6,7 @@ var_dump(getimagesize(__DIR__ . '/bug71848.jpg', $info)); var_dump(array_keys($info)); ?> --EXPECT-- -array(7) { +array(9) { [0]=> int(8) [1]=> @@ -21,6 +21,10 @@ array(7) { int(3) ["mime"]=> string(10) "image/jpeg" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" } array(2) { [0]=> diff --git a/ext/standard/tests/image/bug72278.phpt b/ext/standard/tests/image/bug72278.phpt index 074338c18ae..21079246a5d 100644 --- a/ext/standard/tests/image/bug72278.phpt +++ b/ext/standard/tests/image/bug72278.phpt @@ -8,7 +8,7 @@ var_dump(getimagesize(FILENAME)); ?> --EXPECTF-- Warning: getimagesize(): Corrupt JPEG data: 3 extraneous bytes before marker in %s%ebug72278.php on line %d -array(7) { +array(9) { [0]=> int(300) [1]=> @@ -23,4 +23,8 @@ array(7) { int(3) ["mime"]=> string(10) "image/jpeg" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" } diff --git a/ext/standard/tests/image/bug75708.phpt b/ext/standard/tests/image/bug75708.phpt index 3c81c67cf5d..b1a5ee6116c 100644 --- a/ext/standard/tests/image/bug75708.phpt +++ b/ext/standard/tests/image/bug75708.phpt @@ -41,7 +41,7 @@ var_dump(getimagesize('fs://bug75708.jpg', $info)); ?> --EXPECT-- -array(7) { +array(9) { [0]=> int(10) [1]=> @@ -56,5 +56,8 @@ array(7) { int(3) ["mime"]=> string(10) "image/jpeg" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" } - diff --git a/ext/standard/tests/image/getimagesize.phpt b/ext/standard/tests/image/getimagesize.phpt index 472be1d25e3..81c4f8dc6b5 100644 --- a/ext/standard/tests/image/getimagesize.phpt +++ b/ext/standard/tests/image/getimagesize.phpt @@ -23,9 +23,9 @@ GetImageSize() var_dump($result); ?> --EXPECT-- -array(17) { +array(18) { ["test-1pix.bmp"]=> - array(6) { + array(8) { [0]=> int(1) [1]=> @@ -38,9 +38,13 @@ array(17) { int(24) ["mime"]=> string(9) "image/bmp" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" } ["test12pix.webp"]=> - array(6) { + array(8) { [0]=> int(4) [1]=> @@ -53,9 +57,13 @@ array(17) { int(8) ["mime"]=> string(10) "image/webp" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" } ["test1bpix.bmp"]=> - array(6) { + array(8) { [0]=> int(1) [1]=> @@ -68,9 +76,13 @@ array(17) { int(32) ["mime"]=> string(9) "image/bmp" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" } ["test1pix.avif"]=> - array(7) { + array(9) { [0]=> int(102) [1]=> @@ -85,9 +97,13 @@ array(17) { int(4) ["mime"]=> string(10) "image/avif" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" } ["test1pix.bmp"]=> - array(6) { + array(8) { [0]=> int(1) [1]=> @@ -100,9 +116,13 @@ array(17) { int(24) ["mime"]=> string(9) "image/bmp" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" } ["test1pix.jp2"]=> - array(7) { + array(9) { [0]=> int(1) [1]=> @@ -117,9 +137,13 @@ array(17) { int(3) ["mime"]=> string(9) "image/jp2" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" } ["test1pix.jpc"]=> - array(7) { + array(9) { [0]=> int(1) [1]=> @@ -134,9 +158,13 @@ array(17) { int(3) ["mime"]=> string(24) "application/octet-stream" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" } ["test1pix.jpg"]=> - array(7) { + array(9) { [0]=> int(1) [1]=> @@ -151,9 +179,13 @@ array(17) { int(3) ["mime"]=> string(10) "image/jpeg" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" } ["test2pix.gif"]=> - array(7) { + array(9) { [0]=> int(2) [1]=> @@ -168,9 +200,13 @@ array(17) { int(3) ["mime"]=> string(9) "image/gif" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" } ["test3llpix.webp"]=> - array(6) { + array(8) { [0]=> int(1) [1]=> @@ -183,9 +219,13 @@ array(17) { int(8) ["mime"]=> string(10) "image/webp" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" } ["test3pix.webp"]=> - array(6) { + array(8) { [0]=> int(1) [1]=> @@ -198,9 +238,13 @@ array(17) { int(8) ["mime"]=> string(10) "image/webp" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" } ["test4pix.gif"]=> - array(7) { + array(9) { [0]=> int(4) [1]=> @@ -215,9 +259,34 @@ array(17) { int(3) ["mime"]=> string(9) "image/gif" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" + } + ["test4pix.heic"]=> + array(9) { + [0]=> + int(54) + [1]=> + int(84) + [2]=> + int(20) + [3]=> + string(22) "width="54" height="84"" + ["bits"]=> + int(8) + ["channels"]=> + int(3) + ["mime"]=> + string(10) "image/heif" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" } ["test4pix.iff"]=> - array(6) { + array(8) { [0]=> int(4) [1]=> @@ -230,9 +299,13 @@ array(17) { int(4) ["mime"]=> string(9) "image/iff" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" } ["test4pix.png"]=> - array(6) { + array(8) { [0]=> int(4) [1]=> @@ -245,9 +318,13 @@ array(17) { int(4) ["mime"]=> string(9) "image/png" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" } ["test4pix.psd"]=> - array(5) { + array(7) { [0]=> int(4) [1]=> @@ -258,9 +335,13 @@ array(17) { string(20) "width="4" height="1"" ["mime"]=> string(9) "image/psd" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" } ["test4pix.swf"]=> - array(5) { + array(7) { [0]=> int(550) [1]=> @@ -271,9 +352,13 @@ array(17) { string(24) "width="550" height="400"" ["mime"]=> string(29) "application/x-shockwave-flash" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" } ["test4pix.tiff"]=> - array(5) { + array(7) { [0]=> int(4) [1]=> @@ -284,5 +369,9 @@ array(17) { string(20) "width="4" height="1"" ["mime"]=> string(10) "image/tiff" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" } } diff --git a/ext/standard/tests/image/getimagesize_246x247.phpt b/ext/standard/tests/image/getimagesize_246x247.phpt index c716ac3aebc..abf5bec0412 100644 --- a/ext/standard/tests/image/getimagesize_246x247.phpt +++ b/ext/standard/tests/image/getimagesize_246x247.phpt @@ -25,7 +25,7 @@ GetImageSize() with 246x247 pixels --EXPECT-- array(1) { ["246x247.png"]=> - array(6) { + array(8) { [0]=> int(246) [1]=> @@ -38,5 +38,9 @@ array(1) { int(4) ["mime"]=> string(9) "image/png" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" } } diff --git a/ext/standard/tests/image/getimagesize_256_ico.phpt b/ext/standard/tests/image/getimagesize_256_ico.phpt index 770985c6aec..7f1fff07a3a 100644 --- a/ext/standard/tests/image/getimagesize_256_ico.phpt +++ b/ext/standard/tests/image/getimagesize_256_ico.phpt @@ -9,7 +9,7 @@ var_dump(getimagesize(__DIR__ . "/32x256.ico")); ===DONE=== --EXPECT-- *** Testing getimagesize() : 256px ico *** -array(6) { +array(8) { [0]=> int(32) [1]=> @@ -22,5 +22,9 @@ array(6) { int(8) ["mime"]=> string(24) "image/vnd.microsoft.icon" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" } ===DONE=== diff --git a/ext/standard/tests/image/getimagesize_384x385.phpt b/ext/standard/tests/image/getimagesize_384x385.phpt index 57dc8a71921..69705080cad 100644 --- a/ext/standard/tests/image/getimagesize_384x385.phpt +++ b/ext/standard/tests/image/getimagesize_384x385.phpt @@ -25,7 +25,7 @@ GetImageSize() with 384x385 pixels --EXPECT-- array(1) { ["384x385.png"]=> - array(6) { + array(8) { [0]=> int(384) [1]=> @@ -38,5 +38,9 @@ array(1) { int(1) ["mime"]=> string(9) "image/png" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" } } diff --git a/ext/standard/tests/image/getimagesize_basic.phpt b/ext/standard/tests/image/getimagesize_basic.phpt index f1a6d108d31..3dd1823437c 100644 --- a/ext/standard/tests/image/getimagesize_basic.phpt +++ b/ext/standard/tests/image/getimagesize_basic.phpt @@ -44,7 +44,7 @@ foreach($imagetype_filenames as $key => $filename) { *** Testing getimagesize() : basic functionality *** -- GIF image file (200x100.gif) -- -array(7) { +array(9) { [0]=> int(200) [1]=> @@ -59,12 +59,16 @@ array(7) { int(3) ["mime"]=> string(9) "image/gif" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" } array(0) { } -- JPEG image file (200x100.jpg) -- -array(7) { +array(9) { [0]=> int(200) [1]=> @@ -79,6 +83,10 @@ array(7) { int(3) ["mime"]=> string(10) "image/jpeg" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" } array(1) { ["APP0"]=> @@ -86,7 +94,7 @@ array(1) { } -- PNG image file (200x100.png) -- -array(6) { +array(8) { [0]=> int(200) [1]=> @@ -99,12 +107,16 @@ array(6) { int(8) ["mime"]=> string(9) "image/png" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" } array(0) { } -- SWF image file (200x100.swf) -- -array(5) { +array(7) { [0]=> int(200) [1]=> @@ -115,12 +127,16 @@ array(5) { string(24) "width="200" height="100"" ["mime"]=> string(29) "application/x-shockwave-flash" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" } array(0) { } -- BMP image file (200x100.bmp) -- -array(6) { +array(8) { [0]=> int(200) [1]=> @@ -133,12 +149,16 @@ array(6) { int(24) ["mime"]=> string(9) "image/bmp" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" } array(0) { } -- TIFF intel byte order image file (200x100.tiff) -- -array(5) { +array(7) { [0]=> int(200) [1]=> @@ -149,12 +169,16 @@ array(5) { string(24) "width="200" height="100"" ["mime"]=> string(10) "image/tiff" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" } array(0) { } -- JPC image file (test1pix.jpc) -- -array(7) { +array(9) { [0]=> int(1) [1]=> @@ -169,12 +193,16 @@ array(7) { int(3) ["mime"]=> string(24) "application/octet-stream" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" } array(0) { } -- JP2 image file (test1pix.jp2) -- -array(7) { +array(9) { [0]=> int(1) [1]=> @@ -189,12 +217,16 @@ array(7) { int(3) ["mime"]=> string(9) "image/jp2" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" } array(0) { } -- IFF image file (test4pix.iff) -- -array(6) { +array(8) { [0]=> int(4) [1]=> @@ -207,6 +239,10 @@ array(6) { int(4) ["mime"]=> string(9) "image/iff" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" } array(0) { } diff --git a/ext/standard/tests/image/getimagesize_swc.phpt b/ext/standard/tests/image/getimagesize_swc.phpt index 7dff107d477..f5031e7a223 100644 --- a/ext/standard/tests/image/getimagesize_swc.phpt +++ b/ext/standard/tests/image/getimagesize_swc.phpt @@ -13,7 +13,7 @@ if (!defined("IMAGETYPE_SWC")) { var_dump(getimagesize(__DIR__ . "/test13pix.swf")); ?> --EXPECT-- -array(5) { +array(7) { [0]=> int(550) [1]=> @@ -24,4 +24,8 @@ array(5) { string(24) "width="550" height="400"" ["mime"]=> string(29) "application/x-shockwave-flash" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" } diff --git a/ext/standard/tests/image/getimagesize_tif_mm.phpt b/ext/standard/tests/image/getimagesize_tif_mm.phpt index cd6f32f4d37..58047f6134d 100644 --- a/ext/standard/tests/image/getimagesize_tif_mm.phpt +++ b/ext/standard/tests/image/getimagesize_tif_mm.phpt @@ -9,7 +9,7 @@ var_dump($arr); ?> --EXPECT-- *** Testing getimagesize() : tiff_mm format *** -array(5) { +array(7) { [0]=> int(2) [1]=> @@ -20,6 +20,10 @@ array(5) { string(20) "width="2" height="2"" ["mime"]=> string(10) "image/tiff" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" } array(0) { } diff --git a/ext/standard/tests/image/getimagesize_variation4.phpt b/ext/standard/tests/image/getimagesize_variation4.phpt index 658ce84d518..49b924ffe77 100644 --- a/ext/standard/tests/image/getimagesize_variation4.phpt +++ b/ext/standard/tests/image/getimagesize_variation4.phpt @@ -17,7 +17,7 @@ var_dump( $info ); ?> --EXPECT-- *** Testing getimagesize() : variation *** -array(5) { +array(7) { [0]=> int(550) [1]=> @@ -28,6 +28,10 @@ array(5) { string(24) "width="550" height="400"" ["mime"]=> string(29) "application/x-shockwave-flash" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" } array(0) { } diff --git a/ext/standard/tests/image/getimagesize_variation_005.phpt b/ext/standard/tests/image/getimagesize_variation_005.phpt index 8e471e50a23..c6d083b23b5 100644 --- a/ext/standard/tests/image/getimagesize_variation_005.phpt +++ b/ext/standard/tests/image/getimagesize_variation_005.phpt @@ -17,7 +17,7 @@ var_dump( $info ); ?> --EXPECT-- *** Testing getimagesize() : basic functionality *** -array(5) { +array(7) { [0]=> int(550) [1]=> @@ -28,6 +28,10 @@ array(5) { string(24) "width="550" height="400"" ["mime"]=> string(29) "application/x-shockwave-flash" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" } array(0) { } diff --git a/ext/standard/tests/image/getimagesize_wbmp.phpt b/ext/standard/tests/image/getimagesize_wbmp.phpt index 0b0ebe52347..97151d84124 100644 --- a/ext/standard/tests/image/getimagesize_wbmp.phpt +++ b/ext/standard/tests/image/getimagesize_wbmp.phpt @@ -9,7 +9,7 @@ var_dump($arr); ?> --EXPECT-- *** Testing getimagesize() : wbmp format *** -array(5) { +array(7) { [0]=> int(75) [1]=> @@ -20,6 +20,10 @@ array(5) { string(22) "width="75" height="50"" ["mime"]=> string(18) "image/vnd.wap.wbmp" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" } array(0) { } diff --git a/ext/standard/tests/image/getimagesize_xbm.phpt b/ext/standard/tests/image/getimagesize_xbm.phpt index 5ecd6ad2063..4f7f7965dd6 100644 --- a/ext/standard/tests/image/getimagesize_xbm.phpt +++ b/ext/standard/tests/image/getimagesize_xbm.phpt @@ -9,7 +9,7 @@ var_dump($arr); ?> --EXPECT-- *** Testing getimagesize() : xbm format *** -array(5) { +array(7) { [0]=> int(75) [1]=> @@ -20,6 +20,10 @@ array(5) { string(22) "width="75" height="50"" ["mime"]=> string(9) "image/xbm" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" } array(0) { } diff --git a/ext/standard/tests/image/getimagesizefromstring1.phpt b/ext/standard/tests/image/getimagesizefromstring1.phpt index 6202b38e896..0037c292f70 100644 --- a/ext/standard/tests/image/getimagesizefromstring1.phpt +++ b/ext/standard/tests/image/getimagesizefromstring1.phpt @@ -14,7 +14,7 @@ var_dump($i1); var_dump($i2); ?> --EXPECT-- -array(7) { +array(9) { [0]=> int(120) [1]=> @@ -29,8 +29,12 @@ array(7) { int(3) ["mime"]=> string(9) "image/gif" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" } -array(7) { +array(9) { [0]=> int(120) [1]=> @@ -45,4 +49,8 @@ array(7) { int(3) ["mime"]=> string(9) "image/gif" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" } diff --git a/ext/standard/tests/image/image_type_to_extension.phpt b/ext/standard/tests/image/image_type_to_extension.phpt index 9b0d991d070..3f3e5f28051 100644 --- a/ext/standard/tests/image/image_type_to_extension.phpt +++ b/ext/standard/tests/image/image_type_to_extension.phpt @@ -25,6 +25,7 @@ image_type_to_extension() "IMAGETYPE_XBM" => IMAGETYPE_XBM, "IMAGETYPE_WEBP" => IMAGETYPE_WEBP, "IMAGETYPE_AVIF" => IMAGETYPE_AVIF, + "IMAGETYPE_HEIF" => IMAGETYPE_HEIF, ); foreach($constants as $name => $constant) { printf("Constant: %s\n\tWith dot: %s\n\tWithout dot: %s\n", $name, image_type_to_extension($constant), image_type_to_extension($constant, false)); @@ -89,6 +90,9 @@ Constant: IMAGETYPE_WEBP Constant: IMAGETYPE_AVIF With dot: .avif Without dot: avif +Constant: IMAGETYPE_HEIF + With dot: .heif + Without dot: heif bool(false) bool(false) Done diff --git a/ext/standard/tests/image/image_type_to_mime_type.phpt b/ext/standard/tests/image/image_type_to_mime_type.phpt index 5877efe531f..0102955babe 100644 --- a/ext/standard/tests/image/image_type_to_mime_type.phpt +++ b/ext/standard/tests/image/image_type_to_mime_type.phpt @@ -24,7 +24,7 @@ image_type_to_mime_type() var_dump($result); ?> --EXPECT-- -array(17) { +array(18) { ["test-1pix.bmp"]=> string(9) "image/bmp" ["test12pix.webp"]=> @@ -49,6 +49,8 @@ array(17) { string(10) "image/webp" ["test4pix.gif"]=> string(9) "image/gif" + ["test4pix.heic"]=> + string(10) "image/heif" ["test4pix.iff"]=> string(9) "image/iff" ["test4pix.png"]=> diff --git a/ext/standard/tests/image/image_type_to_mime_type_basic.phpt b/ext/standard/tests/image/image_type_to_mime_type_basic.phpt index bf5a1ee2509..6fb51540076 100644 --- a/ext/standard/tests/image/image_type_to_mime_type_basic.phpt +++ b/ext/standard/tests/image/image_type_to_mime_type_basic.phpt @@ -22,7 +22,8 @@ $image_types = array ( IMAGETYPE_WBMP, IMAGETYPE_JPEG2000, IMAGETYPE_XBM, - IMAGETYPE_WEBP + IMAGETYPE_WEBP, + IMAGETYPE_HEIF, ); foreach($image_types as $image_type) { @@ -51,5 +52,6 @@ string(18) "image/vnd.wap.wbmp" string(24) "application/octet-stream" string(9) "image/xbm" string(10) "image/webp" +string(10) "image/heif" Done image_type_to_mime_type() test diff --git a/ext/standard/tests/image/image_type_to_mime_type_variation3.phpt b/ext/standard/tests/image/image_type_to_mime_type_variation3.phpt index fc17cb5ecd9..8bd62188d21 100644 --- a/ext/standard/tests/image/image_type_to_mime_type_variation3.phpt +++ b/ext/standard/tests/image/image_type_to_mime_type_variation3.phpt @@ -1,78 +1,84 @@ --TEST-- -image_type_to_mime_type() (passinf equivalent integer values) +image_type_to_mime_type() (passing equivalent integer values) --CREDITS-- Sanjay Mantoor --FILE-- ---EXPECTREGEX-- -\*\*\* Testing image_type_to_mime_type\(\) : usage variations \*\*\* +--EXPECT-- +*** Testing image_type_to_mime_type() : usage variations *** -- Iteration 0 -- -string\(24\) "application\/octet-stream" +string(24) "application/octet-stream" -- Iteration 1 -- -string\(9\) "image\/gif" +string(9) "image/gif" -- Iteration 2 -- -string\(10\) "image\/jpeg" +string(10) "image/jpeg" -- Iteration 3 -- -string\(9\) "image\/png" +string(9) "image/png" -- Iteration 4 -- -string\(29\) "application\/x-shockwave-flash" +string(29) "application/x-shockwave-flash" -- Iteration 5 -- -string\(9\) "image\/psd" +string(9) "image/psd" -- Iteration 6 -- -string\(9\) "image\/bmp" +string(9) "image/bmp" -- Iteration 7 -- -string\(10\) "image\/tiff" +string(10) "image/tiff" -- Iteration 8 -- -string\(10\) "image\/tiff" +string(10) "image/tiff" -- Iteration 9 -- -string\(24\) "application\/octet-stream" +string(24) "application/octet-stream" -- Iteration 10 -- -string\(9\) "image\/jp2" +string(9) "image/jp2" -- Iteration 11 -- -string\(24\) "application\/octet-stream" +string(24) "application/octet-stream" -- Iteration 12 -- -string\(24\) "application\/octet-stream" +string(24) "application/octet-stream" -- Iteration 13 -- -string\(2[49]\) "application\/(x-shockwave-flash|octet-stream)" +string(29) "application/x-shockwave-flash" -- Iteration 14 -- -string\(9\) "image\/iff" +string(9) "image/iff" -- Iteration 15 -- -string\(18\) "image\/vnd.wap.wbmp" +string(18) "image/vnd.wap.wbmp" -- Iteration 16 -- -string\(9\) "image\/xbm" +string(9) "image/xbm" -- Iteration 17 -- -string\(24\) "image\/vnd.microsoft.icon" +string(24) "image/vnd.microsoft.icon" -- Iteration 18 -- -string\(10\) "image\/webp" +string(10) "image/webp" -- Iteration 19 -- -string\(10\) "image\/avif" +string(10) "image/avif" -- Iteration 20 -- -string\(24\) "application\/octet-stream" +string(10) "image/heif" + +-- Iteration 999 -- +string(24) "application/octet-stream" diff --git a/ext/standard/tests/image/test4pix.heic b/ext/standard/tests/image/test4pix.heic new file mode 100644 index 00000000000..93ca3ed1faf Binary files /dev/null and b/ext/standard/tests/image/test4pix.heic differ diff --git a/ext/standard/tests/network/setcookie.phpt b/ext/standard/tests/network/setcookie.phpt index f43680a5bce..caf9aa9ae07 100644 --- a/ext/standard/tests/network/setcookie.phpt +++ b/ext/standard/tests/network/setcookie.phpt @@ -19,6 +19,7 @@ setcookie('name', 'value', 0, '', '', FALSE, TRUE); setcookie('name', 'value', ['expires' => $tsp]); setcookie('name', 'value', ['expires' => $tsn, 'path' => '/path/', 'domain' => 'domain.tld', 'secure' => true, 'httponly' => true, 'samesite' => 'Strict']); +setcookie('name', 'value', ['secure' => true, 'partitioned' => true]); $expected = array( 'Set-Cookie: name=deleted; expires='.date('D, d M Y H:i:s', 1).' GMT; Max-Age=0', @@ -34,7 +35,8 @@ $expected = array( 'Set-Cookie: name=value; secure', 'Set-Cookie: name=value; HttpOnly', 'Set-Cookie: name=value; expires='.date('D, d M Y H:i:s', $tsp).' GMT; Max-Age=5', - 'Set-Cookie: name=value; expires='.date('D, d M Y H:i:s', $tsn).' GMT; Max-Age=0; path=/path/; domain=domain.tld; secure; HttpOnly; SameSite=Strict' + 'Set-Cookie: name=value; expires='.date('D, d M Y H:i:s', $tsn).' GMT; Max-Age=0; path=/path/; domain=domain.tld; secure; HttpOnly; SameSite=Strict', + 'Set-Cookie: name=value; secure; Partitioned' ); $headers = headers_list(); diff --git a/ext/standard/tests/network/setcookie_array_option_error.phpt b/ext/standard/tests/network/setcookie_array_option_error.phpt index ad4caf35108..0fb2ae011c3 100644 --- a/ext/standard/tests/network/setcookie_array_option_error.phpt +++ b/ext/standard/tests/network/setcookie_array_option_error.phpt @@ -37,6 +37,12 @@ try { } catch (\ValueError $e) { echo $e->getMessage() . "\n"; } +// Partitioned without secure +try { + setcookie('name', 'value', ['partitioned' => true]); +} catch (\ValueError $e) { + echo $e->getMessage() . "\n"; +} // Arguments after options array (will not be set) try { @@ -66,6 +72,7 @@ setcookie(): option array cannot have numeric keys setcookie(): option "foo" is invalid setcookie(): "path" option cannot contain ",", ";", " ", "\t", "\r", "\n", "\013", or "\014" setcookie(): "domain" option cannot contain ",", ";", " ", "\t", "\r", "\n", "\013", or "\014" +setcookie(): "partitioned" option cannot be used without "secure" option setcookie(): Expects exactly 3 arguments when argument #3 ($expires_or_options) is an array bool(true) array(1) { diff --git a/ext/standard/tests/serialize/oss_fuzz_433303828.phpt b/ext/standard/tests/serialize/oss_fuzz_433303828.phpt new file mode 100644 index 00000000000..fb90b51d4da --- /dev/null +++ b/ext/standard/tests/serialize/oss_fuzz_433303828.phpt @@ -0,0 +1,13 @@ +--TEST-- +OSS-Fuzz #433303828 +--FILE-- + +--EXPECTF-- +Warning: unserialize(): Error at offset 9 of 10 bytes in %s on line %d + +Warning: unserialize(): Error at offset 10 of 11 bytes in %s on line %d diff --git a/ext/standard/tests/serialize/unserialize_mem_leak.phpt b/ext/standard/tests/serialize/unserialize_mem_leak.phpt index 3ddb74a273d..bad689c3705 100644 --- a/ext/standard/tests/serialize/unserialize_mem_leak.phpt +++ b/ext/standard/tests/serialize/unserialize_mem_leak.phpt @@ -1,7 +1,5 @@ --TEST-- Memleaks if unserialize return a self-referenced array/object ---INI-- -report_memleaks=1 --FILE-- +--EXPECTF-- +Fatal error: Bailout in %s on line %d diff --git a/ext/standard/tests/streams/user-stream-error.phpt b/ext/standard/tests/streams/user-stream-error.phpt deleted file mode 100644 index 8ad4be64418..00000000000 --- a/ext/standard/tests/streams/user-stream-error.phpt +++ /dev/null @@ -1,22 +0,0 @@ ---TEST-- -E_ERROR during UserStream Open ---FILE-- - ---EXPECTF-- -Fatal error: Uncaught Error: Call to undefined function _some_undefined_function() in %s%euser-stream-error.php:%d -Stack trace: -#0 [internal function]: FailStream->stream_open('mystream://foo', 'r', 0, NULL) -#1 %s%euser-stream-error.php(%d): fopen('mystream://foo', 'r') -#2 {main} - thrown in %s%euser-stream-error.php on line %d diff --git a/ext/standard/tests/streams/user-stream-open-bailout.phpt b/ext/standard/tests/streams/user-stream-open-bailout.phpt new file mode 100644 index 00000000000..552e32a04a2 --- /dev/null +++ b/ext/standard/tests/streams/user-stream-open-bailout.phpt @@ -0,0 +1,19 @@ +--TEST-- +Bailout (E_ERROR) during UserStream Open +--EXTENSIONS-- +zend_test +--FILE-- + +--EXPECTF-- +Fatal error: Bailout in %s on line %d diff --git a/ext/standard/tests/strings/chr_out_of_range.phpt b/ext/standard/tests/strings/chr_out_of_range.phpt new file mode 100644 index 00000000000..8381850e806 --- /dev/null +++ b/ext/standard/tests/strings/chr_out_of_range.phpt @@ -0,0 +1,15 @@ +--TEST-- +chr() with out of range values +--FILE-- + +--EXPECTF-- +Deprecated: chr(): Providing a value not in-between 0 and 255 is deprecated, this is because a byte value must be in the [0, 255] interval. The value used will be constrained using % 256 in %s on line 3 +bool(true) + +Deprecated: chr(): Providing a value not in-between 0 and 255 is deprecated, this is because a byte value must be in the [0, 255] interval. The value used will be constrained using % 256 in %s on line 4 +bool(true) diff --git a/ext/standard/tests/strings/chr_variation1.phpt b/ext/standard/tests/strings/chr_variation1.phpt index f045fdb54a0..d181e752c2a 100644 --- a/ext/standard/tests/strings/chr_variation1.phpt +++ b/ext/standard/tests/strings/chr_variation1.phpt @@ -5,36 +5,17 @@ Test chr() function : usage variations - test values for $ascii argument echo "*** Testing chr() function: with unexpected inputs for 'ascii' argument ***\n"; -//defining a class -class sample { - public function __toString() { - return "sample object"; - } -} - -//getting the resource -$file_handle = fopen(__FILE__, "r"); - // array with different values for $input -$inputs = array ( - - // integer values -/*1*/ 0, - 1, - 255, - 256, - - // float values -/*5*/ 10.5, - -20.5, - 1.1234e6, - - // boolean values -/*11*/ true, - false, - TRUE, - FALSE, -); +$inputs = [ + 0, + 1, + 255, + // float values + 10.5, + // bool values + true, + false, +]; // loop through with each element of the $inputs array to test chr() function $count = 1; @@ -44,8 +25,6 @@ foreach($inputs as $input) { $count ++; } -fclose($file_handle); //closing the file handle - ?> --EXPECTF-- *** Testing chr() function: with unexpected inputs for 'ascii' argument *** @@ -56,22 +35,10 @@ string(2) "01" -- Iteration 3 -- string(2) "ff" -- Iteration 4 -- -string(2) "00" --- Iteration 5 -- Deprecated: Implicit conversion from float 10.5 to int loses precision in %s on line %d string(2) "0a" +-- Iteration 5 -- +string(2) "01" -- Iteration 6 -- - -Deprecated: Implicit conversion from float -20.5 to int loses precision in %s on line %d -string(2) "ec" --- Iteration 7 -- -string(2) "48" --- Iteration 8 -- -string(2) "01" --- Iteration 9 -- -string(2) "00" --- Iteration 10 -- -string(2) "01" --- Iteration 11 -- string(2) "00" diff --git a/ext/standard/tests/strings/str_replace_variation2.phpt b/ext/standard/tests/strings/str_replace_variation2.phpt index 957c990555e..d8dcd58e1b6 100644 --- a/ext/standard/tests/strings/str_replace_variation2.phpt +++ b/ext/standard/tests/strings/str_replace_variation2.phpt @@ -12,7 +12,7 @@ precision=14 echo "\n*** Testing str_replace() with various subjects ***"; $subject = "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE\000 \x000\x5ACD\0abcd \xXYZ\tabcd $$@#%^&*!~,.:;?: !!Hello, World - ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(256)"; + ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(0)"; /* needles in an array to be compared in the string $string */ $search_str = array ( @@ -48,7 +48,7 @@ $search_str = array ( 'b', '\t', "\t", - chr(128).chr(234).chr(65).chr(255).chr(256), + chr(128).chr(234).chr(65).chr(255).chr(0), $subject ); @@ -65,233 +65,233 @@ for( $i = 0; $i < count($search_str); $i++ ) { *** Testing str_replace() with various subjects *** --- Iteration 0 --- -- String after replacing the search value is => -- -string(181) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE%0 +string(179) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE%0 %00ZCD%0abcd \xXYZ abcd $$@#%^&*!~,.:;?: !!FOUND - ?FOUND chr(0).chr(128).chr(234).chr(65).chr(255).chr(256)" + ?FOUND chr(0).chr(128).chr(234).chr(65).chr(255).chr(0)" -- search string has found '2' times --- Iteration 1 --- -- String after replacing the search value is => -- -string(181) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE%0 +string(179) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE%0 %00ZCD%0abcd \xXYZ abcd $$@#%^&*!~,.:;?: !!FOUND - ?FOUND chr(0).chr(128).chr(234).chr(65).chr(255).chr(256)" + ?FOUND chr(0).chr(128).chr(234).chr(65).chr(255).chr(0)" -- search string has found '2' times --- Iteration 2 --- -- String after replacing the search value is => -- -string(186) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE%0 +string(184) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE%0 %00ZCD%0abcd \xXYZ abcd $$@#%^&*!~,.:;?: FOUND - ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(256)" + ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(0)" -- search string has found '1' times --- Iteration 3 --- -- String after replacing the search value is => -- -string(195) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE%0 +string(193) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE%0 %00ZCD%0abcd \xXYZ abcd $$@#%^&*!~,.:;?: !!Hello, World - ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(256)" + ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(0)" -- search string has found '0' times --- Iteration 4 --- -- String after replacing the search value is => -- -string(186) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE%0 +string(184) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE%0 %00ZCD%0abcd \xXYZ abcd $FOUND: !!Hello, World - ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(256)" + ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(0)" -- search string has found '1' times --- Iteration 5 --- -- String after replacing the search value is => -- -string(195) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE%0 +string(193) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE%0 %00ZCD%0abcd \xXYZ abcd $$@#%^&*!~,.:;?: !!Hello, World - ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(256)" + ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(0)" -- search string has found '0' times --- Iteration 6 --- -- String after replacing the search value is => -- -string(195) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE%0 +string(193) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE%0 %00ZCD%0abcd \xXYZ abcd $$@#%^&*!~,.:;?: !!Hello, World - ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(256)" + ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(0)" -- search string has found '0' times --- Iteration 7 --- -- String after replacing the search value is => -- -string(193) "Hello, world,0120333.3445FOUND67 NULL TRUE FALSE%0 +string(191) "Hello, world,0120333.3445FOUND67 NULL TRUE FALSE%0 %00ZCD%0abcd \xXYZ abcd $$@#%^&*!~,.:;?: !!Hello, World - ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(256)" + ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(0)" -- search string has found '1' times --- Iteration 8 --- -- String after replacing the search value is => -- -string(195) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE%0 +string(193) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE%0 %00ZCD%0abcd \xXYZ abcd $$@#%^&*!~,.:;?: !!Hello, World - ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(256)" + ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(0)" -- search string has found '0' times --- Iteration 9 --- -- String after replacing the search value is => -- -string(197) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE%0 +string(195) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE%0 %00ZCD%0FOUND \xXYZ FOUND $$@#%^&*!~,.:;?: !!Hello, World - ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(256)" + ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(0)" -- search string has found '2' times --- Iteration 10 --- -- String after replacing the search value is => -- -string(197) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE%0 +string(195) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE%0 %00ZCD%0abcd \xFOUND abcd $$@#%^&*!~,.:;?: !!Hello, World - ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(256)" + ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(0)" -- search string has found '1' times --- Iteration 11 --- -- String after replacing the search value is => -- -string(196) "Hello, world,0120333.3445-1.234567 FOUND TRUE FALSE%0 +string(194) "Hello, world,0120333.3445-1.234567 FOUND TRUE FALSE%0 %00ZCD%0abcd \xXYZ abcd $$@#%^&*!~,.:;?: !!Hello, World - ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(256)" + ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(0)" -- search string has found '1' times --- Iteration 12 --- -- String after replacing the search value is => -- -string(211) "Hello, world,FOUND12FOUND333.3445-1.234567 NULL TRUE FALSE%0 +string(213) "Hello, world,FOUND12FOUND333.3445-1.234567 NULL TRUE FALSE%0 %0FOUNDZCD%0abcd \xXYZ abcd $$@#%^&*!~,.:;?: !!Hello, World - ?Hello, World chr(FOUND).chr(128).chr(234).chr(65).chr(255).chr(256)" --- search string has found '4' times + ?Hello, World chr(FOUND).chr(128).chr(234).chr(65).chr(255).chr(FOUND)" +-- search string has found '5' times --- Iteration 13 --- -- String after replacing the search value is => -- -string(211) "Hello, world,FOUND12FOUND333.3445-1.234567 NULL TRUE FALSE%0 +string(213) "Hello, world,FOUND12FOUND333.3445-1.234567 NULL TRUE FALSE%0 %0FOUNDZCD%0abcd \xXYZ abcd $$@#%^&*!~,.:;?: !!Hello, World - ?Hello, World chr(FOUND).chr(128).chr(234).chr(65).chr(255).chr(256)" --- search string has found '4' times + ?Hello, World chr(FOUND).chr(128).chr(234).chr(65).chr(255).chr(FOUND)" +-- search string has found '5' times --- Iteration 14 --- -- String after replacing the search value is => -- -string(195) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE%0 +string(193) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE%0 %00ZCD%0abcd \xXYZ abcd $$@#%^&*!~,.:;?: !!Hello, World - ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(256)" + ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(0)" -- search string has found '0' times --- Iteration 15 --- -- String after replacing the search value is => -- -string(335) "Hello,FOUNDworld,0120333.3445-1.234567FOUNDFOUNDFOUNDFOUNDFOUNDFOUNDFOUNDFOUNDFOUNDFOUNDNULLFOUNDTRUEFOUNDFALSE%0 +string(333) "Hello,FOUNDworld,0120333.3445-1.234567FOUNDFOUNDFOUNDFOUNDFOUNDFOUNDFOUNDFOUNDFOUNDFOUNDNULLFOUNDTRUEFOUNDFALSE%0 FOUNDFOUNDFOUNDFOUNDFOUNDFOUNDFOUNDFOUND%00ZCD%0abcdFOUND\xXYZ abcdFOUND$$@#%^&*!~,.:;?:FOUND!!Hello,FOUNDWorld -FOUNDFOUNDFOUNDFOUNDFOUNDFOUNDFOUNDFOUND?Hello,FOUNDWorldFOUNDchr(0).chr(128).chr(234).chr(65).chr(255).chr(256)" +FOUNDFOUNDFOUNDFOUNDFOUNDFOUNDFOUNDFOUND?Hello,FOUNDWorldFOUNDchr(0).chr(128).chr(234).chr(65).chr(255).chr(0)" -- search string has found '35' times --- Iteration 16 --- -- String after replacing the search value is => -- -string(207) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSEFOUND +string(205) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSEFOUND FOUND0ZCDFOUNDabcd \xXYZ abcd $$@#%^&*!~,.:;?: !!Hello, World - ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(256)" + ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(0)" -- search string has found '3' times --- Iteration 17 --- -- String after replacing the search value is => -- -string(198) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE%0 +string(196) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE%0 FOUNDZCD%0abcd \xXYZ abcd $$@#%^&*!~,.:;?: !!Hello, World - ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(256)" + ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(0)" -- search string has found '1' times --- Iteration 18 --- -- String after replacing the search value is => -- -string(198) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE%0 +string(196) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE%0 %00FOUNDD%0abcd \xXYZ abcd $$@#%^&*!~,.:;?: !!Hello, World - ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(256)" + ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(0)" -- search string has found '1' times --- Iteration 19 --- -- String after replacing the search value is => -- -string(198) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE%0 +string(196) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE%0 FOUNDZCD%0abcd \xXYZ abcd $$@#%^&*!~,.:;?: !!Hello, World - ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(256)" + ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(0)" -- search string has found '1' times --- Iteration 20 --- -- String after replacing the search value is => -- -string(198) "Hello, world,0120333FOUND445-1.234567 NULL TRUE FALSE%0 +string(196) "Hello, world,0120333FOUND445-1.234567 NULL TRUE FALSE%0 %00ZCD%0abcd \xXYZ abcd $$@#%^&*!~,.:;?: !!Hello, World - ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(256)" + ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(0)" -- search string has found '1' times --- Iteration 21 --- -- String after replacing the search value is => -- -string(207) "Hello, world,0FOUND20333.3445-FOUND.234567 NULL TRUE FALSE%0 +string(205) "Hello, world,0FOUND20333.3445-FOUND.234567 NULL TRUE FALSE%0 %00ZCD%0abcd \xXYZ abcd $$@#%^&*!~,.:;?: !!Hello, World - ?Hello, World chr(0).chr(FOUND28).chr(234).chr(65).chr(255).chr(256)" + ?Hello, World chr(0).chr(FOUND28).chr(234).chr(65).chr(255).chr(0)" -- search string has found '3' times --- Iteration 22 --- -- String after replacing the search value is => -- -string(196) "Hello, world,0120333.3445-1.234567 NULL FOUND FALSE%0 +string(194) "Hello, world,0120333.3445-1.234567 NULL FOUND FALSE%0 %00ZCD%0abcd \xXYZ abcd $$@#%^&*!~,.:;?: !!Hello, World - ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(256)" + ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(0)" -- search string has found '1' times --- Iteration 23 --- -- String after replacing the search value is => -- -string(207) "Hello, world,0FOUND20333.3445-FOUND.234567 NULL TRUE FALSE%0 +string(205) "Hello, world,0FOUND20333.3445-FOUND.234567 NULL TRUE FALSE%0 %00ZCD%0abcd \xXYZ abcd $$@#%^&*!~,.:;?: !!Hello, World - ?Hello, World chr(0).chr(FOUND28).chr(234).chr(65).chr(255).chr(256)" + ?Hello, World chr(0).chr(FOUND28).chr(234).chr(65).chr(255).chr(0)" -- search string has found '3' times --- Iteration 24 --- -- String after replacing the search value is => -- -string(207) "Hello, world,0FOUND20333.3445-FOUND.234567 NULL TRUE FALSE%0 +string(205) "Hello, world,0FOUND20333.3445-FOUND.234567 NULL TRUE FALSE%0 %00ZCD%0abcd \xXYZ abcd $$@#%^&*!~,.:;?: !!Hello, World - ?Hello, World chr(0).chr(FOUND28).chr(234).chr(65).chr(255).chr(256)" + ?Hello, World chr(0).chr(FOUND28).chr(234).chr(65).chr(255).chr(0)" -- search string has found '3' times --- Iteration 25 --- -- String after replacing the search value is => -- -string(195) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE%0 +string(193) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE%0 %00ZCD%0abcd \xXYZ abcd $$@#%^&*!~,.:;?: !!Hello, World - ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(256)" + ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(0)" -- search string has found '0' times --- Iteration 26 --- -- String after replacing the search value is => -- -string(195) "Hello, world,0120333.3445-1.234567 NULL TRUE FOUND%0 +string(193) "Hello, world,0120333.3445-1.234567 NULL TRUE FOUND%0 %00ZCD%0abcd \xXYZ abcd $$@#%^&*!~,.:;?: !!Hello, World - ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(256)" + ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(0)" -- search string has found '1' times --- Iteration 27 --- -- String after replacing the search value is => -- -string(335) "Hello,FOUNDworld,0120333.3445-1.234567FOUNDFOUNDFOUNDFOUNDFOUNDFOUNDFOUNDFOUNDFOUNDFOUNDNULLFOUNDTRUEFOUNDFALSE%0 +string(333) "Hello,FOUNDworld,0120333.3445-1.234567FOUNDFOUNDFOUNDFOUNDFOUNDFOUNDFOUNDFOUNDFOUNDFOUNDNULLFOUNDTRUEFOUNDFALSE%0 FOUNDFOUNDFOUNDFOUNDFOUNDFOUNDFOUNDFOUND%00ZCD%0abcdFOUND\xXYZ abcdFOUND$$@#%^&*!~,.:;?:FOUND!!Hello,FOUNDWorld -FOUNDFOUNDFOUNDFOUNDFOUNDFOUNDFOUNDFOUND?Hello,FOUNDWorldFOUNDchr(0).chr(128).chr(234).chr(65).chr(255).chr(256)" +FOUNDFOUNDFOUNDFOUNDFOUNDFOUNDFOUNDFOUND?Hello,FOUNDWorldFOUNDchr(0).chr(128).chr(234).chr(65).chr(255).chr(0)" -- search string has found '35' times --- Iteration 28 --- -- String after replacing the search value is => -- -string(190) "Hello, world,0120333.3445-1.234567FOUNDNULL TRUE FALSE%0 +string(188) "Hello, world,0120333.3445-1.234567FOUNDNULL TRUE FALSE%0 %00ZCD%0abcd \xXYZ abcd $$@#%^&*!~,.:;?: !!Hello, World - ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(256)" + ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(0)" -- search string has found '1' times --- Iteration 29 --- -- String after replacing the search value is => -- -string(203) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE%0 +string(201) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE%0 %00ZCD%0aFOUNDcd \xXYZ aFOUNDcd $$@#%^&*!~,.:;?: !!Hello, World - ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(256)" + ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(0)" -- search string has found '2' times --- Iteration 30 --- -- String after replacing the search value is => -- -string(195) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE%0 +string(193) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE%0 %00ZCD%0abcd \xXYZ abcd $$@#%^&*!~,.:;?: !!Hello, World - ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(256)" + ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(0)" -- search string has found '0' times --- Iteration 31 --- -- String after replacing the search value is => -- -string(199) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE%0 +string(197) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE%0 %00ZCD%0abcd \xXYZFOUNDabcd $$@#%^&*!~,.:;?: !!Hello, World - ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(256)" + ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(0)" -- search string has found '1' times --- Iteration 32 --- -- String after replacing the search value is => -- -string(195) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE%0 +string(193) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE%0 %00ZCD%0abcd \xXYZ abcd $$@#%^&*!~,.:;?: !!Hello, World - ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(256)" + ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(0)" -- search string has found '0' times --- Iteration 33 --- diff --git a/ext/standard/tests/strings/strcasecmp.phpt b/ext/standard/tests/strings/strcasecmp.phpt index e55b2a684fb..1136774b38a 100644 --- a/ext/standard/tests/strings/strcasecmp.phpt +++ b/ext/standard/tests/strings/strcasecmp.phpt @@ -9,7 +9,7 @@ precision = 12 echo "#### Basic and Possible operations ####"; /* creating an array of strings to be compared */ $arrays = array( - array("a", 'A', chr(128), chr(255), chr(256)), + array("a", 'A', chr(128), chr(255), chr(0)), array("acc", "Acc", 'aC', "acCc", 'acd', "?acc", 'Acc!', "$!acc", ";acc"), array("1", "0", 0, "-1", -1, "", TRUE, true, FALSE, "string"), array(10.5, 1.5, 9.5, 11.5, 100.5, 10.5E1, -10.5, 10, 0.5) diff --git a/ext/standard/tests/strings/strcmp.phpt b/ext/standard/tests/strings/strcmp.phpt index 5310566d53b..fa94a9cc3a0 100644 --- a/ext/standard/tests/strings/strcmp.phpt +++ b/ext/standard/tests/strings/strcmp.phpt @@ -9,7 +9,7 @@ precision = 12 echo "#### Basic and Possible operations ####"; /* creating an array of strings to be compared */ $arrays = array( - array("a", "A", 'a', 'A', chr(128), chr(255), chr(256)), + array("a", "A", 'a', 'A', chr(128), chr(255), chr(0)), array("acc", "Acc", 'ac', "accc", 'acd', "?acc", 'acc!', "$!acc", ";acc"), array("1", "0", 0, "-1", -1, "", TRUE, FALSE, "string"), array(10.5, 1.5, 9.5, 11.5, 100.5, 10.5E1, -10.5, 10, 0.5) diff --git a/ext/standard/tests/strings/strlen.phpt b/ext/standard/tests/strings/strlen.phpt index b98111f15e6..b1ff4f4e74d 100644 --- a/ext/standard/tests/strings/strlen.phpt +++ b/ext/standard/tests/strings/strlen.phpt @@ -24,8 +24,8 @@ $strings = array( "Hello, World", "\0000", // len = 2 "0", 0, - "\t", // len = 1 - '\t', // len = 2 + "\t", // len = 1 + '\t', // len = 2 TRUE, FALSE, "Hello, World\0", @@ -36,7 +36,7 @@ $strings = array( "Hello, World", "Hello, World\t", "Hello, World\\", " ", - chr(128).chr(234).chr(65).chr(255).chr(256), + chr(128).chr(234).chr(65).chr(255).chr(0), "abcdefghijklmnopqrstuvwxyz0123456789~!@#$%^&*()_+=|?><-;:$ []{}{{{}}}[[[[]][]]]***&&&^^%$###@@!!@#$%&^&**/////|\\\\\\ @@ -113,11 +113,11 @@ var_dump(strlen("{$str}S")); echo "\n--- strlen for long float values ---\n"; /* Here two different outputs, which depends on the rounding value before converting to string. Here Precision = 12 */ -var_dump(strlen(10.55555555555555555555555555)); // len = 13 -var_dump(strlen(10.55555555595555555555555555)); // len = 12 +var_dump(strlen(10.55555555555555555555555555)); // len = 13 +var_dump(strlen(10.55555555595555555555555555)); // len = 12 echo "\n--- Nested strlen() ---\n"; -var_dump(strlen(strlen("Hello"))); // len=1 +var_dump(strlen(strlen("Hello"))); // len=1 echo "Done\n"; ?> diff --git a/ext/standard/tests/strings/strncasecmp_variation6.phpt b/ext/standard/tests/strings/strncasecmp_variation6.phpt index 78a0ddd549b..3a7b90616a2 100644 --- a/ext/standard/tests/strings/strncasecmp_variation6.phpt +++ b/ext/standard/tests/strings/strncasecmp_variation6.phpt @@ -10,7 +10,7 @@ echo "*** Test strncasecmp() function: with binary inputs ***\n"; echo "\n-- Checking with all 256 characters given, in binary format --\n"; /* loop through to get all 256 character's equivalent binary value, and check working of strncasecmp() */ $count = 1; -for($ASCII = 0; $ASCII <= 255; $ASCII++) { +for($ASCII = 0; $ASCII < 255; $ASCII++) { $str1 = decbin($ASCII); //ASCII value in binary form $str2 = decbin( ord( chr($ASCII) ) ); //Getting equivalent ASCII value for the character in binary form echo "-- Iteration $count --\n"; @@ -21,7 +21,7 @@ for($ASCII = 0; $ASCII <= 255; $ASCII++) { echo "\n-- Checking with out of character's range, given in binary format --\n"; $str1 = decbin(256); -$str2 = decbin( ord( chr(256) )); +$str2 = decbin( ord( chr(0) )); var_dump( strncasecmp($str1, $str2, 8) ); //comparing all the 8-bits; expected: int(1) echo "\n*** Done ***\n"; @@ -795,9 +795,6 @@ int(0) -- Iteration 255 -- int(0) int(0) --- Iteration 256 -- -int(0) -int(0) -- Checking with out of character's range, given in binary format -- int(1) diff --git a/ext/standard/tests/strings/strpos_variation1.phpt b/ext/standard/tests/strings/strpos_variation1.phpt index f28517316dc..d01b9eba24d 100644 --- a/ext/standard/tests/strings/strpos_variation1.phpt +++ b/ext/standard/tests/strings/strpos_variation1.phpt @@ -9,8 +9,8 @@ echo bin2hex( chr(128) ) ." => "; var_dump( strpos($string, chr(128)) ); echo bin2hex( chr(255) ) ." => "; var_dump( strpos($string, chr(255), 3) ); -echo bin2hex( chr(256) ) ." => "; -var_dump( strpos($string, chr(256)) ); +echo bin2hex( chr(0) ) ." => "; +var_dump( strpos($string, chr(0)) ); ?> DONE diff --git a/ext/standard/tests/strings/strstr_variation1.phpt b/ext/standard/tests/strings/strstr_variation1.phpt index aade1fd5f85..30699702f88 100644 --- a/ext/standard/tests/strings/strstr_variation1.phpt +++ b/ext/standard/tests/strings/strstr_variation1.phpt @@ -9,8 +9,8 @@ echo bin2hex( chr(128) ) ." => "; var_dump( bin2hex( strstr($string, chr(128) ) ) ); echo bin2hex( chr(255) ) ." => "; var_dump( bin2hex( strstr($string, chr(255) ) ) ); -echo bin2hex( chr(256) ) ." => "; -var_dump( bin2hex( strstr($string, chr(256) ) ) ); +echo bin2hex( chr(0) ) ." => "; +var_dump( bin2hex( strstr($string, chr(0) ) ) ); ?> DONE diff --git a/ext/standard/tests/strings/substr_count_variation_001.phpt b/ext/standard/tests/strings/substr_count_variation_001.phpt index d76c56d60fb..d7ac3dcd22d 100644 --- a/ext/standard/tests/strings/substr_count_variation_001.phpt +++ b/ext/standard/tests/strings/substr_count_variation_001.phpt @@ -14,10 +14,10 @@ var_dump( substr_count("abcabcabcabcabc", "abca") ); var_dump( substr_count("abcabcabcabcabc", "abca", 2) ); echo "\n-- complex strings containing other than 7-bit chars --\n"; -$str = chr(128).chr(129).chr(128).chr(256).chr(255).chr(254).chr(255); +$str = chr(128).chr(129).chr(128).chr(0).chr(255).chr(254).chr(255); var_dump(substr_count($str, chr(128))); var_dump(substr_count($str, chr(255))); -var_dump(substr_count($str, chr(256))); +var_dump(substr_count($str, chr(0))); echo "\n-- heredoc string --\n"; $string = <<id, IPC_STAT, &stat) == 0) { zval *item; /* now pull out members of data and set them in the stat buffer */ - if ((item = zend_hash_str_find(Z_ARRVAL_P(data), "msg_perm.uid", sizeof("msg_perm.uid") - 1)) != NULL) { + if ((item = zend_hash_str_find(data, ZEND_STRL("msg_perm.uid"))) != NULL) { stat.msg_perm.uid = zval_get_long(item); } - if ((item = zend_hash_str_find(Z_ARRVAL_P(data), "msg_perm.gid", sizeof("msg_perm.gid") - 1)) != NULL) { + if ((item = zend_hash_str_find(data, ZEND_STRL("msg_perm.gid"))) != NULL) { stat.msg_perm.gid = zval_get_long(item); } - if ((item = zend_hash_str_find(Z_ARRVAL_P(data), "msg_perm.mode", sizeof("msg_perm.mode") - 1)) != NULL) { + if ((item = zend_hash_str_find(data, ZEND_STRL("msg_perm.mode"))) != NULL) { stat.msg_perm.mode = zval_get_long(item); } - if ((item = zend_hash_str_find(Z_ARRVAL_P(data), "msg_qbytes", sizeof("msg_qbytes") - 1)) != NULL) { + if ((item = zend_hash_str_find(data, ZEND_STRL("msg_qbytes"))) != NULL) { stat.msg_qbytes = zval_get_long(item); } if (msgctl(mq->id, IPC_SET, &stat) == 0) { @@ -169,28 +169,27 @@ PHP_FUNCTION(msg_stat_queue) sysvmsg_queue_t *mq = NULL; struct msqid_ds stat; - RETVAL_FALSE; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &queue, sysvmsg_queue_ce) == FAILURE) { RETURN_THROWS(); } mq = Z_SYSVMSG_QUEUE_P(queue); - if (msgctl(mq->id, IPC_STAT, &stat) == 0) { - array_init(return_value); - - add_assoc_long(return_value, "msg_perm.uid", stat.msg_perm.uid); - add_assoc_long(return_value, "msg_perm.gid", stat.msg_perm.gid); - add_assoc_long(return_value, "msg_perm.mode", stat.msg_perm.mode); - add_assoc_long(return_value, "msg_stime", stat.msg_stime); - add_assoc_long(return_value, "msg_rtime", stat.msg_rtime); - add_assoc_long(return_value, "msg_ctime", stat.msg_ctime); - add_assoc_long(return_value, "msg_qnum", stat.msg_qnum); - add_assoc_long(return_value, "msg_qbytes", stat.msg_qbytes); - add_assoc_long(return_value, "msg_lspid", stat.msg_lspid); - add_assoc_long(return_value, "msg_lrpid", stat.msg_lrpid); + if (msgctl(mq->id, IPC_STAT, &stat) != 0) { + RETURN_FALSE; } + + array_init_size(return_value, 10); + add_assoc_long(return_value, "msg_perm.uid", stat.msg_perm.uid); + add_assoc_long(return_value, "msg_perm.gid", stat.msg_perm.gid); + add_assoc_long(return_value, "msg_perm.mode", stat.msg_perm.mode); + add_assoc_long(return_value, "msg_stime", stat.msg_stime); + add_assoc_long(return_value, "msg_rtime", stat.msg_rtime); + add_assoc_long(return_value, "msg_ctime", stat.msg_ctime); + add_assoc_long(return_value, "msg_qnum", stat.msg_qnum); + add_assoc_long(return_value, "msg_qbytes", stat.msg_qbytes); + add_assoc_long(return_value, "msg_lspid", stat.msg_lspid); + add_assoc_long(return_value, "msg_lrpid", stat.msg_lrpid); } /* }}} */ @@ -203,11 +202,7 @@ PHP_FUNCTION(msg_queue_exists) RETURN_THROWS(); } - if (msgget(key, 0) < 0) { - RETURN_FALSE; - } - - RETURN_TRUE; + RETURN_BOOL(msgget(key, 0) >= 0); } /* }}} */ @@ -251,11 +246,7 @@ PHP_FUNCTION(msg_remove_queue) mq = Z_SYSVMSG_QUEUE_P(queue); - if (msgctl(mq->id, IPC_RMID, NULL) == 0) { - RETVAL_TRUE; - } else { - RETVAL_FALSE; - } + RETURN_BOOL(msgctl(mq->id, IPC_RMID, NULL) == 0); } /* }}} */ @@ -270,8 +261,6 @@ PHP_FUNCTION(msg_receive) struct php_msgbuf *messagebuffer = NULL; /* buffer to transmit */ int result; - RETVAL_FALSE; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "Olzlz|blz", &queue, sysvmsg_queue_ce, &desiredmsgtype, &out_msgtype, &maxsize, &out_message, &do_unserialize, &flags, &zerrcode) == FAILURE) { @@ -337,6 +326,7 @@ PHP_FUNCTION(msg_receive) if (zerrcode) { ZEND_TRY_ASSIGN_REF_LONG(zerrcode, errno); } + RETVAL_FALSE; } efree(messagebuffer); } @@ -353,8 +343,6 @@ PHP_FUNCTION(msg_send) int result; size_t message_len = 0; - RETVAL_FALSE; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "Olz|bbz", &queue, sysvmsg_queue_ce, &msgtype, &message, &do_serialize, &blocking, &zerror) == FAILURE) { RETURN_THROWS(); @@ -395,10 +383,12 @@ PHP_FUNCTION(msg_send) message_len = spprintf(&p, 0, ZEND_LONG_FMT, Z_LVAL_P(message)); break; case IS_FALSE: - message_len = spprintf(&p, 0, "0"); + p = "0"; + message_len = 1; break; case IS_TRUE: - message_len = spprintf(&p, 0, "1"); + p = "1"; + message_len = 1; break; case IS_DOUBLE: message_len = spprintf(&p, 0, "%F", Z_DVAL_P(message)); @@ -412,7 +402,7 @@ PHP_FUNCTION(msg_send) messagebuffer = safe_emalloc(message_len, 1, sizeof(struct php_msgbuf)); memcpy(messagebuffer->mtext, p, message_len + 1); - if (Z_TYPE_P(message) != IS_STRING) { + if (Z_TYPE_P(message) == IS_LONG || Z_TYPE_P(message) == IS_DOUBLE) { efree(p); } } @@ -429,8 +419,9 @@ PHP_FUNCTION(msg_send) if (zerror) { ZEND_TRY_ASSIGN_REF_LONG(zerror, errno); } + RETURN_FALSE; } else { - RETVAL_TRUE; + RETURN_TRUE; } } /* }}} */ diff --git a/ext/sysvsem/sysvsem.c b/ext/sysvsem/sysvsem.c index 481d8ce28cc..99ebda92273 100644 --- a/ext/sysvsem/sysvsem.c +++ b/ext/sysvsem/sysvsem.c @@ -266,7 +266,7 @@ PHP_FUNCTION(sem_get) /* }}} */ /* {{{ php_sysvsem_semop */ -static void php_sysvsem_semop(INTERNAL_FUNCTION_PARAMETERS, int acquire) +static void php_sysvsem_semop(INTERNAL_FUNCTION_PARAMETERS, bool acquire) { zval *arg_id; bool nowait = 0; @@ -311,14 +311,14 @@ static void php_sysvsem_semop(INTERNAL_FUNCTION_PARAMETERS, int acquire) /* {{{ Acquires the semaphore with the given id, blocking if necessary */ PHP_FUNCTION(sem_acquire) { - php_sysvsem_semop(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1); + php_sysvsem_semop(INTERNAL_FUNCTION_PARAM_PASSTHRU, true); } /* }}} */ /* {{{ Releases the semaphore with the given id */ PHP_FUNCTION(sem_release) { - php_sysvsem_semop(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0); + php_sysvsem_semop(INTERNAL_FUNCTION_PARAM_PASSTHRU, false); } /* }}} */ diff --git a/ext/sysvshm/php_sysvshm.h b/ext/sysvshm/php_sysvshm.h index e11caa6c61b..9576349e06d 100644 --- a/ext/sysvshm/php_sysvshm.h +++ b/ext/sysvshm/php_sysvshm.h @@ -41,17 +41,17 @@ typedef struct { typedef struct { zend_long key; - zend_long length; - zend_long next; + size_t length; + size_t next; char mem; } sysvshm_chunk; typedef struct { char magic[8]; - zend_long start; - zend_long end; - zend_long free; - zend_long total; + size_t start; + size_t end; + size_t free; + size_t total; } sysvshm_chunk_head; typedef struct { diff --git a/ext/sysvshm/sysvshm.c b/ext/sysvshm/sysvshm.c index 332a8b47af1..c1372368a34 100644 --- a/ext/sysvshm/sysvshm.c +++ b/ext/sysvshm/sysvshm.c @@ -90,9 +90,9 @@ ZEND_GET_MODULE(sysvshm) /* TODO: Make this thread-safe. */ sysvshm_module php_sysvshm; -static int php_put_shm_data(sysvshm_chunk_head *ptr, zend_long key, const char *data, zend_long len); -static zend_long php_check_shm_data(sysvshm_chunk_head *ptr, zend_long key); -static int php_remove_shm_data(sysvshm_chunk_head *ptr, zend_long shm_varpos); +static bool php_put_shm_data(sysvshm_chunk_head *ptr, zend_long key, const zend_string *data); +static ssize_t php_check_shm_data(sysvshm_chunk_head *ptr, zend_long key); +static void php_remove_shm_data(sysvshm_chunk_head *ptr, size_t shm_varpos); /* {{{ PHP_MINIT_FUNCTION */ PHP_MINIT_FUNCTION(sysvshm) @@ -235,7 +235,6 @@ PHP_FUNCTION(shm_remove) PHP_FUNCTION(shm_put_var) { zval *shm_id, *arg_var; - int ret; zend_long shm_key; sysvshm_shm *shm_list_ptr; smart_str shm_var = {0}; @@ -262,13 +261,17 @@ PHP_FUNCTION(shm_put_var) RETURN_THROWS(); } + if (UNEXPECTED(shm_var.s == NULL)) { + RETURN_THROWS(); + } + /* insert serialized variable into shared memory */ - ret = php_put_shm_data(shm_list_ptr->ptr, shm_key, shm_var.s? ZSTR_VAL(shm_var.s) : NULL, shm_var.s? ZSTR_LEN(shm_var.s) : 0); + bool ret = php_put_shm_data(shm_list_ptr->ptr, shm_key, shm_var.s); /* free string */ smart_str_free(&shm_var); - if (ret == -1) { + if (!ret) { php_error_docref(NULL, E_WARNING, "Not enough shared memory left"); RETURN_FALSE; } @@ -283,7 +286,6 @@ PHP_FUNCTION(shm_get_var) zend_long shm_key; sysvshm_shm *shm_list_ptr; char *shm_data; - zend_long shm_varpos; sysvshm_chunk *shm_var; php_unserialize_data_t var_hash; @@ -299,9 +301,9 @@ PHP_FUNCTION(shm_get_var) /* setup string-variable and serialize */ /* get serialized variable from shared memory */ - shm_varpos = php_check_shm_data(shm_list_ptr->ptr, shm_key); + ssize_t shm_varpos = php_check_shm_data(shm_list_ptr->ptr, shm_key); - if (shm_varpos < 0) { + if (shm_varpos == -1) { php_error_docref(NULL, E_WARNING, "Variable key " ZEND_LONG_FMT " doesn't exist", shm_key); RETURN_FALSE; } @@ -342,7 +344,7 @@ PHP_FUNCTION(shm_has_var) PHP_FUNCTION(shm_remove_var) { zval *shm_id; - zend_long shm_key, shm_varpos; + zend_long shm_key; sysvshm_shm *shm_list_ptr; if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "Ol", &shm_id, sysvshm_ce, &shm_key)) { @@ -355,9 +357,9 @@ PHP_FUNCTION(shm_remove_var) RETURN_THROWS(); } - shm_varpos = php_check_shm_data(shm_list_ptr->ptr, shm_key); + ssize_t shm_varpos = php_check_shm_data(shm_list_ptr->ptr, shm_key); - if (shm_varpos < 0) { + if (shm_varpos == -1) { php_error_docref(NULL, E_WARNING, "Variable key " ZEND_LONG_FMT " doesn't exist", shm_key); RETURN_FALSE; } @@ -366,44 +368,41 @@ PHP_FUNCTION(shm_remove_var) } /* }}} */ -/* {{{ php_put_shm_data +/* {{{ * inserts an ascii-string into shared memory */ -static int php_put_shm_data(sysvshm_chunk_head *ptr, zend_long key, const char *data, zend_long len) +static bool php_put_shm_data(sysvshm_chunk_head *ptr, zend_long key, const zend_string *data) { sysvshm_chunk *shm_var; - zend_long total_size; - zend_long shm_varpos; + ssize_t shm_varpos; - total_size = ((zend_long) (len + sizeof(sysvshm_chunk) - 1) / sizeof(zend_long)) * sizeof(zend_long) + sizeof(zend_long); /* zend_long alligment */ + size_t total_size = ((zend_long) (ZSTR_LEN(data) + sizeof(sysvshm_chunk) - 1) / sizeof(zend_long)) * sizeof(zend_long) + sizeof(zend_long); /* zend_long alligment */ if ((shm_varpos = php_check_shm_data(ptr, key)) > 0) { php_remove_shm_data(ptr, shm_varpos); } if (ptr->free < total_size) { - return -1; /* not enough memory */ + return false; /* not enough memory */ } shm_var = (sysvshm_chunk *) ((char *) ptr + ptr->end); shm_var->key = key; - shm_var->length = len; + shm_var->length = ZSTR_LEN(data); shm_var->next = total_size; - memcpy(&(shm_var->mem), data, len); + memcpy(&(shm_var->mem), ZSTR_VAL(data), ZSTR_LEN(data)); ptr->end += total_size; ptr->free -= total_size; - return 0; + return true; } /* }}} */ -/* {{{ php_check_shm_data */ -static zend_long php_check_shm_data(sysvshm_chunk_head *ptr, zend_long key) +static ssize_t php_check_shm_data(sysvshm_chunk_head *ptr, zend_long key) { - zend_long pos; sysvshm_chunk *shm_var; ZEND_ASSERT(ptr); - pos = ptr->start; + size_t pos = ptr->start; for (;;) { if (pos >= ptr->end) { @@ -421,27 +420,22 @@ static zend_long php_check_shm_data(sysvshm_chunk_head *ptr, zend_long key) } return -1; } -/* }}} */ -/* {{{ php_remove_shm_data */ -static int php_remove_shm_data(sysvshm_chunk_head *ptr, zend_long shm_varpos) +static void php_remove_shm_data(sysvshm_chunk_head *ptr, size_t shm_varpos) { sysvshm_chunk *chunk_ptr, *next_chunk_ptr; - zend_long memcpy_len; ZEND_ASSERT(ptr); chunk_ptr = (sysvshm_chunk *) ((char *) ptr + shm_varpos); next_chunk_ptr = (sysvshm_chunk *) ((char *) ptr + shm_varpos + chunk_ptr->next); - memcpy_len = ptr->end-shm_varpos - chunk_ptr->next; + size_t memcpy_len = ptr->end-shm_varpos - chunk_ptr->next; ptr->free += chunk_ptr->next; ptr->end -= chunk_ptr->next; if (memcpy_len > 0) { memmove(chunk_ptr, next_chunk_ptr, memcpy_len); } - return 0; } -/* }}} */ #endif /* HAVE_SYSVSHM */ diff --git a/ext/sysvshm/sysvshm.stub.php b/ext/sysvshm/sysvshm.stub.php index 4b6770063a3..c89f67bc068 100644 --- a/ext/sysvshm/sysvshm.stub.php +++ b/ext/sysvshm/sysvshm.stub.php @@ -12,7 +12,7 @@ final class SysvSharedMemory function shm_attach(int $key, ?int $size = null, int $permissions = 0666): SysvSharedMemory|false {} -function shm_detach(SysvSharedMemory $shm): bool {} +function shm_detach(SysvSharedMemory $shm): true {} function shm_has_var(SysvSharedMemory $shm, int $key): bool {} diff --git a/ext/sysvshm/sysvshm_arginfo.h b/ext/sysvshm/sysvshm_arginfo.h index bca40b0e094..c3b803c37ae 100644 --- a/ext/sysvshm/sysvshm_arginfo.h +++ b/ext/sysvshm/sysvshm_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 93677b78d9aaa4d6dbb5d1dcf3e79a8418add5c0 */ + * Stub hash: 792c695a705678a3779d62cef8a5136069f98dee */ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_shm_attach, 0, 1, SysvSharedMemory, MAY_BE_FALSE) ZEND_ARG_TYPE_INFO(0, key, IS_LONG, 0) @@ -7,7 +7,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_shm_attach, 0, 1, SysvShared ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, permissions, IS_LONG, 0, "0666") ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_shm_detach, 0, 1, _IS_BOOL, 0) +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_shm_detach, 0, 1, IS_TRUE, 0) ZEND_ARG_OBJ_INFO(0, shm, SysvSharedMemory, 0) ZEND_END_ARG_INFO() @@ -16,7 +16,9 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_shm_has_var, 0, 2, _IS_BOOL, 0) ZEND_ARG_TYPE_INFO(0, key, IS_LONG, 0) ZEND_END_ARG_INFO() -#define arginfo_shm_remove arginfo_shm_detach +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_shm_remove, 0, 1, _IS_BOOL, 0) + ZEND_ARG_OBJ_INFO(0, shm, SysvSharedMemory, 0) +ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_shm_put_var, 0, 3, _IS_BOOL, 0) ZEND_ARG_OBJ_INFO(0, shm, SysvSharedMemory, 0) diff --git a/ext/sysvshm/tests/serialize_exception.phpt b/ext/sysvshm/tests/serialize_exception.phpt new file mode 100644 index 00000000000..aae237e0fb3 --- /dev/null +++ b/ext/sysvshm/tests/serialize_exception.phpt @@ -0,0 +1,27 @@ +--TEST-- +__serialize() exception in shm_put_var() +--EXTENSIONS-- +sysvshm +--FILE-- +getMessage() . "\n"; +} + +shm_remove($s); + +?> +--EXPECT-- +no diff --git a/ext/tidy/tests/025.phpt b/ext/tidy/tests/025.phpt index eda79a98851..d6419934911 100644 --- a/ext/tidy/tests/025.phpt +++ b/ext/tidy/tests/025.phpt @@ -19,7 +19,7 @@ $n = $tidy->Root()->child[0]->child[1]->child[0]; var_dump($n->isComment()); var_dump((string)$n); var_dump((bool)$n); -var_dump((double)$n); +var_dump((float)$n); var_dump((int)$n); var_dump($tidy->Root()->child[0]->child[0]->hasSiblings()); diff --git a/ext/tidy/tests/031.phpt b/ext/tidy/tests/031.phpt index e41d94be2f7..3b0ac39b209 100644 --- a/ext/tidy/tests/031.phpt +++ b/ext/tidy/tests/031.phpt @@ -7,7 +7,7 @@ tidy --FILE-- '; -$config = array('doctype' => 'php'); +$config = array('doctype' => 'auto'); $tidy = tidy_parse_string($buffer, $config); var_dump(tidy_config_count($tidy)); diff --git a/ext/tidy/tests/tidy_error1.phpt b/ext/tidy/tests/tidy_error1.phpt index 0660f37437e..5e7593762a9 100644 --- a/ext/tidy/tests/tidy_error1.phpt +++ b/ext/tidy/tests/tidy_error1.phpt @@ -32,7 +32,15 @@ try { echo $e::class, ": ", $e->getMessage(), PHP_EOL; } -$config = ['doctype' => 'php', 0 => 'value2']; +$config = ['doctype' => 'php']; + +try { + var_dump($tidy->parseString($buffer, $config)); +} catch (\TypeError $e) { + echo $e::class, ": ", $e->getMessage(), PHP_EOL; +} + +$config = ['doctype' => 'auto', 0 => 'value2']; try { var_dump($tidy->parseString($buffer, $config)); @@ -45,4 +53,5 @@ try { ValueError: tidy::parseString(): Argument #2 ($config) Unknown Tidy configuration option "bogus" TypeError: tidy::parseString(): Argument #2 ($config) must be of type array with keys as string ValueError: tidy::parseString(): Argument #2 ($config) Attempting to set read-only option "doctype-mode" +TypeError: tidy::parseString(): Argument #2 ($config) option "doctype" does not accept "php" as a value TypeError: tidy::parseString(): Argument #2 ($config) must be of type array with keys as string diff --git a/ext/tidy/tidy.c b/ext/tidy/tidy.c index fe2a0648af6..16c09a96a75 100644 --- a/ext/tidy/tidy.c +++ b/ext/tidy/tidy.c @@ -114,7 +114,7 @@ static inline PHPTidyObj *php_tidy_fetch_object(zend_object *obj) { /* }}} */ /* {{{ ext/tidy prototypes */ -static zend_string *php_tidy_file_to_mem(const char *, bool); +static zend_string *php_tidy_file_to_mem(const zend_string *, bool); static void tidy_object_free_storage(zend_object *); static zend_object *tidy_object_new_node(zend_class_entry *); static zend_object *tidy_object_new_doc(zend_class_entry *); @@ -124,7 +124,6 @@ static void tidy_doc_update_properties(PHPTidyObj *); static void tidy_add_node_default_properties(PHPTidyObj *); static void *php_tidy_get_opt_val(const PHPTidyDoc *, TidyOption, TidyOptionType *); static void php_tidy_create_node(INTERNAL_FUNCTION_PARAMETERS, tidy_base_nodetypes); -static zend_result _php_tidy_set_tidy_opt(TidyDoc, const char *, zval *, uint32_t arg); static zend_result _php_tidy_apply_config_array(TidyDoc doc, const HashTable *ht_options, uint32_t arg); static PHP_INI_MH(php_tidy_set_clean_output); static void php_tidy_clean_output_start(const char *name, size_t name_len); @@ -216,58 +215,6 @@ static zend_result php_tidy_apply_config(TidyDoc doc, const zend_string *str_str return SUCCESS; } -static zend_result _php_tidy_set_tidy_opt(TidyDoc doc, const char *optname, zval *value, uint32_t arg) -{ - TidyOption opt = tidyGetOptionByName(doc, optname); - zend_string *str, *tmp_str; - zend_long lval; - - if (!opt) { - zend_argument_value_error(arg, "Unknown Tidy configuration option \"%s\"", optname); - return FAILURE; - } - -#if defined(HAVE_TIDYOPTGETCATEGORY) - if (tidyOptGetCategory(opt) == TidyInternalCategory) { -#else - if (tidyOptIsReadOnly(opt)) { -#endif - zend_argument_value_error(arg, "Attempting to set read-only option \"%s\"", optname); - return FAILURE; - } - - switch(tidyOptGetType(opt)) { - case TidyString: - str = zval_get_tmp_string(value, &tmp_str); - if (tidyOptSetValue(doc, tidyOptGetId(opt), ZSTR_VAL(str))) { - zend_tmp_string_release(tmp_str); - return SUCCESS; - } - zend_tmp_string_release(tmp_str); - break; - - case TidyInteger: - lval = zval_get_long(value); - if (tidyOptSetInt(doc, tidyOptGetId(opt), lval)) { - return SUCCESS; - } - break; - - case TidyBoolean: - lval = zval_get_long(value); - if (tidyOptSetBool(doc, tidyOptGetId(opt), lval)) { - return SUCCESS; - } - break; - - default: - php_error_docref(NULL, E_WARNING, "Unable to determine type of configuration option"); - break; - } - - return FAILURE; -} - static void tidy_create_node_object(zval *zv, PHPTidyDoc *ptdoc, TidyNode node) { object_init_ex(zv, tidy_ce_node); @@ -299,7 +246,7 @@ static void php_tidy_quick_repair(INTERNAL_FUNCTION_PARAMETERS, bool is_file) Z_PARAM_BOOL(use_include_path) ZEND_PARSE_PARAMETERS_END(); - if (!(data = php_tidy_file_to_mem(ZSTR_VAL(arg1), use_include_path))) { + if (!(data = php_tidy_file_to_mem(arg1, use_include_path))) { RETURN_FALSE; } } else { @@ -381,12 +328,12 @@ static void php_tidy_quick_repair(INTERNAL_FUNCTION_PARAMETERS, bool is_file) tidyRelease(doc); } -static zend_string *php_tidy_file_to_mem(const char *filename, bool use_include_path) +static zend_string *php_tidy_file_to_mem(const zend_string *filename, bool use_include_path) { php_stream *stream; zend_string *data = NULL; - if (!(stream = php_stream_open_wrapper(filename, "rb", (use_include_path ? USE_PATH : 0), NULL))) { + if (!(stream = php_stream_open_wrapper(ZSTR_VAL(filename), "rb", (use_include_path ? USE_PATH : 0), NULL))) { return NULL; } if ((data = php_stream_copy_to_mem(stream, PHP_STREAM_COPY_ALL, 0)) == NULL) { @@ -720,28 +667,19 @@ static void *php_tidy_get_opt_val(const PHPTidyDoc *ptdoc, TidyOption opt, TidyO { *type = tidyOptGetType(opt); - switch (*type) { - case TidyString: { - const char *val = tidyOptGetValue(ptdoc->doc, tidyOptGetId(opt)); - if (val) { - return (void *) zend_string_init(val, strlen(val), 0); - } else { - return (void *) ZSTR_EMPTY_ALLOC(); - } + if (*type == TidyString) { + const char *val = tidyOptGetValue(ptdoc->doc, tidyOptGetId(opt)); + if (val) { + return (void *) zend_string_init(val, strlen(val), 0); + } else { + return (void *) ZSTR_EMPTY_ALLOC(); } - break; - - case TidyInteger: - return (void *) (uintptr_t) tidyOptGetInt(ptdoc->doc, tidyOptGetId(opt)); - break; - - case TidyBoolean: - return (void *) tidyOptGetBool(ptdoc->doc, tidyOptGetId(opt)); - break; + } else if (*type == TidyInteger) { + return (void *) (uintptr_t) tidyOptGetInt(ptdoc->doc, tidyOptGetId(opt)); + } else { + ZEND_ASSERT(*type == TidyBoolean); + return (void *) tidyOptGetBool(ptdoc->doc, tidyOptGetId(opt)); } - - /* should not happen */ - return NULL; } static void php_tidy_create_node(INTERNAL_FUNCTION_PARAMETERS, tidy_base_nodetypes node_type) @@ -776,31 +714,74 @@ static void php_tidy_create_node(INTERNAL_FUNCTION_PARAMETERS, tidy_base_nodetyp tidy_create_node_object(return_value, obj->ptdoc, node); } + +static bool php_tidy_set_tidy_opt(TidyDoc doc, const char *optname, zval *value, uint32_t arg) +{ + TidyOption opt = tidyGetOptionByName(doc, optname); + zend_long lval; + + if (!opt) { + zend_argument_value_error(arg, "Unknown Tidy configuration option \"%s\"", optname); + return false; + } + +#if defined(HAVE_TIDYOPTGETCATEGORY) + if (tidyOptGetCategory(opt) == TidyInternalCategory) { +#else + if (tidyOptIsReadOnly(opt)) { +#endif + zend_argument_value_error(arg, "Attempting to set read-only option \"%s\"", optname); + return false; + } + + TidyOptionType type = tidyOptGetType(opt); + if (type == TidyString) { + zend_string *tmp_str; + const zend_string *str = zval_get_tmp_string(value, &tmp_str); + const bool result = tidyOptSetValue(doc, tidyOptGetId(opt), ZSTR_VAL(str)); + if (UNEXPECTED(!result)) { + zend_argument_type_error(arg, "option \"%s\" does not accept \"%s\" as a value", optname, ZSTR_VAL(str)); + } + zend_tmp_string_release(tmp_str); + return result; + } else if (type == TidyInteger) { + lval = zval_get_long(value); + return tidyOptSetInt(doc, tidyOptGetId(opt), lval); + } else { + ZEND_ASSERT(type == TidyBoolean); + lval = zval_get_long(value); + return tidyOptSetBool(doc, tidyOptGetId(opt), lval); + } +} + static zend_result _php_tidy_apply_config_array(TidyDoc doc, const HashTable *ht_options, uint32_t arg) { zval *opt_val; zend_string *opt_name; if (!HT_IS_PACKED(ht_options)) { + bool has_failures = false; ZEND_HASH_MAP_FOREACH_STR_KEY_VAL(ht_options, opt_name, opt_val) { if (opt_name == NULL) { zend_argument_type_error(arg, "must be of type array with keys as string"); return FAILURE; } - _php_tidy_set_tidy_opt(doc, ZSTR_VAL(opt_name), opt_val, arg); + has_failures = has_failures || !php_tidy_set_tidy_opt(doc, ZSTR_VAL(opt_name), opt_val, arg); } ZEND_HASH_FOREACH_END(); - return SUCCESS; + return has_failures ? FAILURE : SUCCESS; } else { zend_argument_type_error(arg, "must be of type array with keys as string"); return FAILURE; } } -static zend_result php_tidy_parse_string(PHPTidyObj *obj, const char *string, uint32_t len, const char *enc) +static zend_result php_tidy_parse_string(PHPTidyObj *obj, const zend_string *string, const char *enc) { TidyBuffer buf; - if(enc) { + ZEND_ASSERT(!ZEND_SIZE_T_UINT_OVFL(ZSTR_LEN(string))); + + if (enc) { if (tidySetCharEncoding(obj->ptdoc->doc, enc) < 0) { php_error_docref(NULL, E_WARNING, "Could not set encoding \"%s\"", enc); return FAILURE; @@ -810,9 +791,9 @@ static zend_result php_tidy_parse_string(PHPTidyObj *obj, const char *string, ui obj->ptdoc->initialized = true; tidyBufInit(&buf); - tidyBufAttach(&buf, (byte *) string, len); + tidyBufAttach(&buf, (byte *) ZSTR_VAL(string), (unsigned int) ZSTR_LEN(string)); if (tidyParseBuffer(obj->ptdoc->doc, &buf) < 0) { - php_error_docref(NULL, E_WARNING, "%s", obj->ptdoc->errbuf->bp); + php_error_docref(NULL, E_WARNING, "%s", (const char*) obj->ptdoc->errbuf->bp); return FAILURE; } tidy_doc_update_properties(obj); @@ -1016,7 +997,7 @@ PHP_FUNCTION(tidy_parse_string) obj = Z_TIDY_P(return_value); if (php_tidy_apply_config(obj->ptdoc->doc, options_str, options_ht, 2) != SUCCESS - || php_tidy_parse_string(obj, ZSTR_VAL(input), (uint32_t)ZSTR_LEN(input), enc) != SUCCESS) { + || php_tidy_parse_string(obj, input, enc) != SUCCESS) { zval_ptr_dtor(return_value); RETURN_FALSE; } @@ -1069,7 +1050,7 @@ PHP_FUNCTION(tidy_parse_file) Z_PARAM_BOOL(use_include_path) ZEND_PARSE_PARAMETERS_END(); - if (!(contents = php_tidy_file_to_mem(ZSTR_VAL(inputfile), use_include_path))) { + if (!(contents = php_tidy_file_to_mem(inputfile, use_include_path))) { php_error_docref(NULL, E_WARNING, "Cannot load \"%s\" into memory%s", ZSTR_VAL(inputfile), (use_include_path) ? " (using include path)" : ""); RETURN_FALSE; } @@ -1084,7 +1065,7 @@ PHP_FUNCTION(tidy_parse_file) obj = Z_TIDY_P(return_value); if (php_tidy_apply_config(obj->ptdoc->doc, options_str, options_ht, 2) != SUCCESS - || php_tidy_parse_string(obj, ZSTR_VAL(contents), (uint32_t)ZSTR_LEN(contents), enc) != SUCCESS) { + || php_tidy_parse_string(obj, contents, enc) != SUCCESS) { zval_ptr_dtor(return_value); RETVAL_FALSE; } @@ -1322,18 +1303,10 @@ PHP_FUNCTION(tidy_getopt) case TidyInteger: RETURN_LONG((zend_long)optval); - break; case TidyBoolean: RETURN_BOOL(optval); - break; - - default: - php_error_docref(NULL, E_WARNING, "Unable to determine type of configuration option"); - break; } - - RETURN_FALSE; } /* }}} */ @@ -1357,7 +1330,7 @@ PHP_METHOD(tidy, __construct) obj = Z_TIDY_P(ZEND_THIS); if (inputfile) { - if (!(contents = php_tidy_file_to_mem(ZSTR_VAL(inputfile), use_include_path))) { + if (!(contents = php_tidy_file_to_mem(inputfile, use_include_path))) { zend_throw_error(zend_ce_exception, "Cannot load \"%s\" into memory%s", ZSTR_VAL(inputfile), (use_include_path) ? " (using include path)" : ""); RETURN_THROWS(); } @@ -1377,7 +1350,7 @@ PHP_METHOD(tidy, __construct) } zend_restore_error_handling(&error_handling); - php_tidy_parse_string(obj, ZSTR_VAL(contents), (uint32_t)ZSTR_LEN(contents), enc); + php_tidy_parse_string(obj, contents, enc); zend_string_release_ex(contents, 0); } @@ -1402,7 +1375,7 @@ PHP_METHOD(tidy, parseFile) obj = Z_TIDY_P(ZEND_THIS); - if (!(contents = php_tidy_file_to_mem(ZSTR_VAL(inputfile), use_include_path))) { + if (!(contents = php_tidy_file_to_mem(inputfile, use_include_path))) { php_error_docref(NULL, E_WARNING, "Cannot load \"%s\" into memory%s", ZSTR_VAL(inputfile), (use_include_path) ? " (using include path)" : ""); RETURN_FALSE; } @@ -1414,7 +1387,7 @@ PHP_METHOD(tidy, parseFile) } RETVAL_BOOL(php_tidy_apply_config(obj->ptdoc->doc, options_str, options_ht, 2) == SUCCESS - && php_tidy_parse_string(obj, ZSTR_VAL(contents), (uint32_t)ZSTR_LEN(contents), enc) == SUCCESS); + && php_tidy_parse_string(obj, contents, enc) == SUCCESS); zend_string_release_ex(contents, 0); } @@ -1442,7 +1415,7 @@ PHP_METHOD(tidy, parseString) obj = Z_TIDY_P(ZEND_THIS); RETURN_BOOL(php_tidy_apply_config(obj->ptdoc->doc, options_str, options_ht, 2) == SUCCESS - && php_tidy_parse_string(obj, ZSTR_VAL(input), (uint32_t)ZSTR_LEN(input), enc) == SUCCESS); + && php_tidy_parse_string(obj, input, enc) == SUCCESS); } diff --git a/ext/uri/php_lexbor.c b/ext/uri/php_lexbor.c index 39b0fb7d09c..5287bbcd902 100644 --- a/ext/uri/php_lexbor.c +++ b/ext/uri/php_lexbor.c @@ -372,7 +372,9 @@ static zend_result lexbor_read_host(const struct uri_internal_t *internal_uri, u smart_str_appendc(&host_str, ']'); ZVAL_NEW_STR(retval, smart_str_extract(&host_str)); - } else if (lexbor_uri->host.type != LXB_URL_HOST_TYPE_EMPTY && lexbor_uri->host.type != LXB_URL_HOST_TYPE__UNDEF) { + } else if (lexbor_uri->host.type == LXB_URL_HOST_TYPE_EMPTY) { + ZVAL_EMPTY_STRING(retval); + } else if (lexbor_uri->host.type != LXB_URL_HOST_TYPE__UNDEF) { switch (read_mode) { case URI_COMPONENT_READ_NORMALIZED_UNICODE: { smart_str host_str = {0}; diff --git a/ext/uri/php_uriparser.c b/ext/uri/php_uriparser.c index 875d72b8524..337e453c6d4 100644 --- a/ext/uri/php_uriparser.c +++ b/ext/uri/php_uriparser.c @@ -21,7 +21,6 @@ #include "Zend/zend_exceptions.h" static void uriparser_free_uri(void *uri); -static void throw_invalid_uri_exception(void); static void *uriparser_malloc(UriMemoryManager *memory_manager, size_t size) { @@ -174,7 +173,7 @@ ZEND_ATTRIBUTE_NONNULL static zend_result uriparser_read_host(const uri_internal UriUriA *uriparser_uri = uriparser_read_uri(internal_uri->uri, read_mode); ZEND_ASSERT(uriparser_uri != NULL); - if (uriparser_uri->hostText.first != NULL && uriparser_uri->hostText.afterLast != NULL && get_text_range_length(&uriparser_uri->hostText) > 0) { + if (uriparser_uri->hostText.first != NULL && uriparser_uri->hostText.afterLast != NULL) { if (uriparser_uri->hostData.ip6 != NULL || uriparser_uri->hostData.ipFuture.first != NULL) { /* the textual representation of the host is always accessible in the .hostText field no matter what the host is */ smart_str host_str = {0}; @@ -293,51 +292,59 @@ static uriparser_uris_t *uriparser_create_uris(void) return uriparser_uris; } -static void throw_invalid_uri_exception(void) -{ - zend_throw_exception(uri_invalid_uri_exception_ce, "The specified URI is malformed", 0); -} - -#define PARSE_URI(dest_uri, uri_str, uriparser_uris, silent) \ - do { \ - if (ZSTR_LEN(uri_str) == 0 || \ - uriParseSingleUriExMmA(dest_uri, ZSTR_VAL(uri_str), ZSTR_VAL(uri_str) + ZSTR_LEN(uri_str), NULL, mm) != URI_SUCCESS \ - ) { \ - efree(uriparser_uris); \ - if (!silent) { \ - throw_invalid_uri_exception(); \ - } \ - return NULL; \ - } \ - } while (0) - void *uriparser_parse_uri_ex(const zend_string *uri_str, const uriparser_uris_t *uriparser_base_urls, bool silent) { - uriparser_uris_t *uriparser_uris = uriparser_create_uris(); + UriUriA uri = {0}; - if (uriparser_base_urls == NULL) { - PARSE_URI(&uriparser_uris->uri, uri_str, uriparser_uris, silent); - uriMakeOwnerMmA(&uriparser_uris->uri, mm); - } else { - UriUriA uri; - - PARSE_URI(&uri, uri_str, uriparser_uris, silent); - - if (uriAddBaseUriExMmA(&uriparser_uris->uri, &uri, &uriparser_base_urls->uri, URI_RESOLVE_STRICTLY, mm) != URI_SUCCESS) { - efree(uriparser_uris); - uriFreeUriMembersMmA(&uri, mm); - if (!silent) { - throw_invalid_uri_exception(); - } - - return NULL; + /* Parse the URI. */ + if (uriParseSingleUriExMmA(&uri, ZSTR_VAL(uri_str), ZSTR_VAL(uri_str) + ZSTR_LEN(uri_str), NULL, mm) != URI_SUCCESS) { + if (!silent) { + zend_throw_exception(uri_invalid_uri_exception_ce, "The specified URI is malformed", 0); } - uriMakeOwnerMmA(&uriparser_uris->uri, mm); - uriFreeUriMembersMmA(&uri, mm); + goto fail; } + if (uriparser_base_urls != NULL) { + UriUriA tmp = {0}; + + /* Combine the parsed URI with the base URI and store the result in 'tmp', + * since the target and source URLs must be distinct. */ + int result = uriAddBaseUriExMmA(&tmp, &uri, &uriparser_base_urls->uri, URI_RESOLVE_STRICTLY, mm); + if (result != URI_SUCCESS) { + if (!silent) { + switch (result) { + case URI_ERROR_ADDBASE_REL_BASE: + zend_throw_exception(uri_invalid_uri_exception_ce, "The specified base URI must be absolute", 0); + break; + default: + /* This should be unreachable in practice. */ + zend_throw_exception(uri_invalid_uri_exception_ce, "Failed to resolve the specified URI against the base URI", 0); + break; + } + } + + goto fail; + } + + /* Store the combined URI back into 'uri'. */ + uriFreeUriMembersMmA(&uri, mm); + uri = tmp; + } + + /* Make the resulting URI independent of the 'uri_str'. */ + uriMakeOwnerMmA(&uri, mm); + + uriparser_uris_t *uriparser_uris = uriparser_create_uris(); + uriparser_uris->uri = uri; + return uriparser_uris; + + fail: + + uriFreeUriMembersMmA(&uri, mm); + + return NULL; } void *uriparser_parse_uri(const zend_string *uri_str, const void *base_url, zval *errors, bool silent) diff --git a/ext/uri/tests/003.phpt b/ext/uri/tests/003.phpt index be607fd6cac..a1918f7a838 100644 --- a/ext/uri/tests/003.phpt +++ b/ext/uri/tests/003.phpt @@ -1,5 +1,5 @@ --TEST-- -Parse URL exotic URLs +Parse special URIs --EXTENSIONS-- uri --FILE-- @@ -8,6 +8,8 @@ uri var_dump(Uri\Rfc3986\Uri::parse("http://username:password@héééostname:9090/gah/../path?arg=vaéue#anchor")); var_dump(Uri\WhatWg\Url::parse("http://username:password@héééostname:9090/gah/../path?arg=vaéue#anchor")); +var_dump(Uri\Rfc3986\Uri::parse("//host123/")); +var_dump(Uri\Rfc3986\Uri::parse("///foo/")); var_dump(Uri\Rfc3986\Uri::parse("/page:1")); var_dump(Uri\WhatWg\Url::parse("/page:1")); @@ -32,6 +34,42 @@ object(Uri\WhatWg\Url)#%d (%d) { ["fragment"]=> string(6) "anchor" } +object(Uri\Rfc3986\Uri)#%d (%d) { + ["scheme"]=> + NULL + ["username"]=> + NULL + ["password"]=> + NULL + ["host"]=> + string(7) "host123" + ["port"]=> + NULL + ["path"]=> + string(1) "/" + ["query"]=> + NULL + ["fragment"]=> + NULL +} +object(Uri\Rfc3986\Uri)#%d (%d) { + ["scheme"]=> + NULL + ["username"]=> + NULL + ["password"]=> + NULL + ["host"]=> + string(0) "" + ["port"]=> + NULL + ["path"]=> + string(5) "/foo/" + ["query"]=> + NULL + ["fragment"]=> + NULL +} object(Uri\Rfc3986\Uri)#%d (%d) { ["scheme"]=> NULL diff --git a/ext/uri/tests/004.phpt b/ext/uri/tests/004.phpt index 10e90dc584a..d22f52f30c4 100644 --- a/ext/uri/tests/004.phpt +++ b/ext/uri/tests/004.phpt @@ -5,12 +5,7 @@ uri --FILE-- getMessage() . "\n"; -} - +var_dump(new Uri\Rfc3986\Uri("")); var_dump(Uri\Rfc3986\Uri::parse("")); try { @@ -29,8 +24,42 @@ var_dump(Uri\WhatWg\Url::parse("http://RuPaul's Drag Race All Stars 7 Winners Ca ?> --EXPECTF-- -The specified URI is malformed -NULL +object(Uri\Rfc3986\Uri)#%d (%d) { + ["scheme"]=> + NULL + ["username"]=> + NULL + ["password"]=> + NULL + ["host"]=> + NULL + ["port"]=> + NULL + ["path"]=> + string(0) "" + ["query"]=> + NULL + ["fragment"]=> + NULL +} +object(Uri\Rfc3986\Uri)#%d (%d) { + ["scheme"]=> + NULL + ["username"]=> + NULL + ["password"]=> + NULL + ["host"]=> + NULL + ["port"]=> + NULL + ["path"]=> + string(0) "" + ["query"]=> + NULL + ["fragment"]=> + NULL +} The specified URI is malformed (MissingSchemeNonRelativeUrl) NULL object(Uri\Rfc3986\Uri)#%d (%d) { diff --git a/ext/uri/tests/012.phpt b/ext/uri/tests/012.phpt index 7c14014fb35..3eb343af535 100644 --- a/ext/uri/tests/012.phpt +++ b/ext/uri/tests/012.phpt @@ -57,7 +57,7 @@ object(Uri\Rfc3986\Uri)#%d (%d) { ["password"]=> NULL ["host"]=> - NULL + string(0) "" ["port"]=> NULL ["path"]=> @@ -75,7 +75,7 @@ object(Uri\WhatWg\Url)#%d (%d) { ["password"]=> NULL ["host"]=> - NULL + string(0) "" ["port"]=> NULL ["path"]=> diff --git a/ext/uri/tests/026.phpt b/ext/uri/tests/026.phpt index 4763ea9d440..47a8597fa2e 100644 --- a/ext/uri/tests/026.phpt +++ b/ext/uri/tests/026.phpt @@ -8,21 +8,27 @@ uri $url1 = Uri\WhatWg\Url::parse("https://example.com"); $url2 = $url1->withHost("test.com"); $url3 = $url2->withHost("t%65st.com"); // test.com -$url4 = $url3->withHost("test.com:8080"); - -var_dump($url1->getAsciiHost()); -var_dump($url2->getAsciiHost()); -var_dump($url3->getAsciiHost()); -var_dump($url4->getAsciiHost()); -var_dump($url4->getPort()); - try { - $url4->withHost("t%3As%2Ft.com"); // t:s/t.com + $url3->withHost("test.com:8080"); } catch (Uri\WhatWg\InvalidUrlException $e) { echo $e->getMessage() . "\n"; } -var_dump($url4->withHost("t:s/t.com")); +var_dump($url1->getAsciiHost()); +var_dump($url2->getAsciiHost()); +var_dump($url3->getAsciiHost()); + +try { + $url3->withHost("t%3As%2Ft.com"); // t:s/t.com +} catch (Uri\WhatWg\InvalidUrlException $e) { + echo $e->getMessage() . "\n"; +} + +try { + $url3->withHost("t:s/t.com"); // t:s/t.com +} catch (Uri\WhatWg\InvalidUrlException $e) { + echo $e->getMessage() . "\n"; +} try { $url2->withHost(null); @@ -38,30 +44,12 @@ var_dump($url2->getAsciiHost()); ?> --EXPECTF-- +The specified host is malformed string(11) "example.com" string(8) "test.com" string(8) "test.com" -string(8) "test.com" -NULL The specified host is malformed (DomainInvalidCodePoint) -object(Uri\WhatWg\Url)#%d (%d) { - ["scheme"]=> - string(5) "https" - ["username"]=> - NULL - ["password"]=> - NULL - ["host"]=> - string(8) "test.com" - ["port"]=> - NULL - ["path"]=> - string(1) "/" - ["query"]=> - NULL - ["fragment"]=> - NULL -} +The specified host is malformed The specified host is malformed (HostMissing) string(7) "foo.com" string(8) "test.com" diff --git a/ext/uri/tests/055.phpt b/ext/uri/tests/055.phpt index 95aac9d3a8b..1b1684d350b 100644 --- a/ext/uri/tests/055.phpt +++ b/ext/uri/tests/055.phpt @@ -12,4 +12,4 @@ try { } ?> --EXPECT-- -The specified URI is malformed +The specified base URI must be absolute diff --git a/ext/xml/tests/bug25666.phpt b/ext/xml/tests/bug25666.phpt index 54103e0c210..8de45a78e2a 100644 --- a/ext/xml/tests/bug25666.phpt +++ b/ext/xml/tests/bug25666.phpt @@ -28,7 +28,6 @@ $parser = xml_parser_create_ns("ISO-8859-1","@"); xml_set_element_handler($parser,'start_elem','end_elem'); xml_parser_set_option($parser,XML_OPTION_CASE_FOLDING,0); xml_parse($parser, $xml); -xml_parser_free($parser); ?> --EXPECT-- string(24) "http://example.com/foo@a" diff --git a/ext/xml/tests/bug26528.phpt b/ext/xml/tests/bug26528.phpt index c100f481bc8..da5dc64f907 100644 --- a/ext/xml/tests/bug26528.phpt +++ b/ext/xml/tests/bug26528.phpt @@ -7,7 +7,6 @@ xml $sample = ""; $parser = xml_parser_create(); $res = xml_parse_into_struct($parser,$sample,$vals,$index); - xml_parser_free($parser); var_dump($vals); ?> --EXPECT-- diff --git a/ext/xml/tests/bug26614.inc b/ext/xml/tests/bug26614.inc index 1b0c94edb9f..c8050e54c77 100644 --- a/ext/xml/tests/bug26614.inc +++ b/ext/xml/tests/bug26614.inc @@ -69,5 +69,4 @@ foreach ($xmls as $desc => $xml) { xml_set_character_data_handler($xml_parser, "characterData"); if (!xml_parse($xml_parser, $xml, true)) echo "Error: ".xml_error_string(xml_get_error_code($xml_parser))."\n"; - xml_parser_free($xml_parser); } diff --git a/ext/xml/tests/bug27908.phpt b/ext/xml/tests/bug27908.phpt index fee8cfb1ee4..e071d531092 100644 --- a/ext/xml/tests/bug27908.phpt +++ b/ext/xml/tests/bug27908.phpt @@ -12,7 +12,6 @@ function x_default_handler($xp,$data) $xp = xml_parser_create(); xml_set_default_handler($xp,'x_default_handler'); xml_parse($xp, '',TRUE); -xml_parser_free($xp); echo "Done\n"; ?> --EXPECT-- diff --git a/ext/xml/tests/bug30875.phpt b/ext/xml/tests/bug30875.phpt index eca12dd74ce..70e26b8ff9b 100644 --- a/ext/xml/tests/bug30875.phpt +++ b/ext/xml/tests/bug30875.phpt @@ -14,7 +14,6 @@ XML; $parser = xml_parser_create(); xml_parse_into_struct($parser, $xml, $vals); -xml_parser_free($parser); var_dump($vals); ?> --EXPECT-- diff --git a/ext/xml/tests/bug35447.phpt b/ext/xml/tests/bug35447.phpt index 229d59314d0..4161d14cd29 100644 --- a/ext/xml/tests/bug35447.phpt +++ b/ext/xml/tests/bug35447.phpt @@ -24,7 +24,6 @@ END_OF_XML; $parser = xml_parser_create_ns('UTF-8'); xml_parser_set_option($parser,XML_OPTION_CASE_FOLDING,0); $result = xml_parse_into_struct($parser, $data, $vals, $index); -xml_parser_free($parser); var_dump($vals); ?> --EXPECT-- diff --git a/ext/xml/tests/bug46699.phpt b/ext/xml/tests/bug46699.phpt index b921ab39b7d..d416c1f7f4b 100644 --- a/ext/xml/tests/bug46699.phpt +++ b/ext/xml/tests/bug46699.phpt @@ -25,7 +25,6 @@ $parser = xml_parser_create_ns("ISO-8859-1","@"); xml_set_default_handler($parser,'defaultfunc'); xml_parser_set_option($parser,XML_OPTION_CASE_FOLDING,0); xml_parse($parser, $xml); -xml_parser_free($parser); ?> --EXPECTF-- diff --git a/ext/xml/tests/bug50576.phpt b/ext/xml/tests/bug50576.phpt index 3279966b3aa..8370943a0f9 100644 --- a/ext/xml/tests/bug50576.phpt +++ b/ext/xml/tests/bug50576.phpt @@ -21,7 +21,6 @@ echo 'Index array' . PHP_EOL; print_r($index); echo 'Vals array' . PHP_EOL; print_r($vals); -xml_parser_free($xml_parser); function startElement($parser, $name, $attribs) { echo $name . PHP_EOL; } function endElement($parser, $name) { echo $name . PHP_EOL; } @@ -29,7 +28,6 @@ $xml_parser = xml_parser_create(); xml_set_element_handler($xml_parser, 'startElement', 'endElement'); xml_parser_set_option($xml_parser, XML_OPTION_SKIP_TAGSTART, 4); xml_parse($xml_parser, $XML); -xml_parser_free($xml_parser); ?> --EXPECT-- diff --git a/ext/xml/tests/bug72714.phpt b/ext/xml/tests/bug72714.phpt index 4e964880ad1..9026dda6ba4 100644 --- a/ext/xml/tests/bug72714.phpt +++ b/ext/xml/tests/bug72714.phpt @@ -22,8 +22,6 @@ function parse($tagstart) { xml_parser_set_option($xml_parser, XML_OPTION_SKIP_TAGSTART, $tagstart); xml_parse($xml_parser, $xml); - - xml_parser_free($xml_parser); } parse(3015809298423721); diff --git a/ext/xml/tests/bug72793.phpt b/ext/xml/tests/bug72793.phpt index b9e53eaf3a5..25bfee990d1 100644 --- a/ext/xml/tests/bug72793.phpt +++ b/ext/xml/tests/bug72793.phpt @@ -33,4 +33,6 @@ $xml_parser->free(); ===DONE=== --EXPECTF-- Deprecated: Function xml_set_object() is deprecated since 8.4, provide a proper method callable to xml_set_*_handler() functions in %s on line %d + +Deprecated: Function xml_parser_free() is deprecated since 8.5, as it has no effect since PHP 8.0 in %s on line %d ===DONE=== diff --git a/ext/xml/tests/bug76874.phpt b/ext/xml/tests/bug76874.phpt index 804fb24241e..1a1fe283d8e 100644 --- a/ext/xml/tests/bug76874.phpt +++ b/ext/xml/tests/bug76874.phpt @@ -27,5 +27,6 @@ $object->test(); ?> ===DONE=== ---EXPECT-- +--EXPECTF-- +Deprecated: Function xml_parser_free() is deprecated since 8.5, as it has no effect since PHP 8.0 in %s on line %d ===DONE=== diff --git a/ext/xml/tests/set_element_handler_trampoline.phpt b/ext/xml/tests/set_element_handler_trampoline.phpt index 884b6db2192..f5eada5c6ca 100644 --- a/ext/xml/tests/set_element_handler_trampoline.phpt +++ b/ext/xml/tests/set_element_handler_trampoline.phpt @@ -42,21 +42,18 @@ echo "Both handlers are trampolines:\n"; $parser = xml_parser_create(); xml_set_element_handler($parser, $startCallback, $endCallback); xml_parse($parser, $xml, true); -xml_parser_free($parser); echo "\nStart handler is trampoline, end handler method string:\n"; $parser = xml_parser_create(); xml_set_object($parser, $customParser); xml_set_element_handler($parser, $startCallback, 'endHandler'); xml_parse($parser, $xml, true); -xml_parser_free($parser); echo "\nEnd handler is trampoline, start handler method string:\n"; $parser = xml_parser_create(); xml_set_object($parser, $customParser); xml_set_element_handler($parser, 'startHandler', $endCallback); xml_parse($parser, $xml, true); -xml_parser_free($parser); ?> --EXPECTF-- diff --git a/ext/xml/tests/set_element_handler_trampoline_errors.phpt b/ext/xml/tests/set_element_handler_trampoline_errors.phpt index 6d35ef5f4d9..52f8efb8ec9 100644 --- a/ext/xml/tests/set_element_handler_trampoline_errors.phpt +++ b/ext/xml/tests/set_element_handler_trampoline_errors.phpt @@ -36,7 +36,6 @@ try { } catch (\Throwable $e) { echo $e::class, ': ', $e->getMessage(), PHP_EOL; } -xml_parser_free($parser); ?> --EXPECT-- diff --git a/ext/xml/tests/set_handler_trampoline.phpt b/ext/xml/tests/set_handler_trampoline.phpt index 74c143c7aac..552df7bf3ee 100644 --- a/ext/xml/tests/set_handler_trampoline.phpt +++ b/ext/xml/tests/set_handler_trampoline.phpt @@ -24,7 +24,6 @@ HERE; $parser = xml_parser_create(); xml_set_processing_instruction_handler($parser, $callback); xml_parse($parser, $xml, true); -xml_parser_free($parser); ?> --EXPECT-- diff --git a/ext/xml/tests/xml001.phpt b/ext/xml/tests/xml001.phpt index 1bbe3c0fced..1bc555efda4 100644 --- a/ext/xml/tests/xml001.phpt +++ b/ext/xml/tests/xml001.phpt @@ -30,7 +30,6 @@ while ($data = fread($fp, 4096)) { } } print "parse complete\n"; -xml_parser_free($xml_parser); function startElement($parser, $name, $attribs) { diff --git a/ext/xml/tests/xml002.phpt b/ext/xml/tests/xml002.phpt index b29c94f83d1..f8b84a75b8e 100644 --- a/ext/xml/tests/xml002.phpt +++ b/ext/xml/tests/xml002.phpt @@ -72,7 +72,6 @@ while ($data = fread($fp, 4096)) { } } print "parse complete\n"; -xml_parser_free($xml_parser); ?> --EXPECT-- diff --git a/ext/xml/tests/xml003.phpt b/ext/xml/tests/xml003.phpt index 2227133caa0..121a6414431 100644 --- a/ext/xml/tests/xml003.phpt +++ b/ext/xml/tests/xml003.phpt @@ -71,7 +71,6 @@ while ($data = fread($fp, 4096)) { } } print "parse complete\n"; -xml_parser_free($xml_parser); ?> --EXPECT-- {?[]}{?[ diff --git a/ext/xml/tests/xml004.phpt b/ext/xml/tests/xml004.phpt index 71c08c2f735..3479892f007 100644 --- a/ext/xml/tests/xml004.phpt +++ b/ext/xml/tests/xml004.phpt @@ -13,7 +13,6 @@ $fp = fopen("xmltest.xml", "r"); while ($data = fread($fp, 4096)) { xml_parse($xp, $data, feof($fp)); } -xml_parser_free($xp); $xp = xml_parser_create(); xml_parser_set_option($xp, XML_OPTION_CASE_FOLDING, true); xml_set_element_handler($xp, "start_element", "end_element"); @@ -21,7 +20,6 @@ $fp = fopen("xmltest.xml", "r"); while ($data = fread($fp, 4096)) { xml_parse($xp, $data, feof($fp)); } -xml_parser_free($xp); function start_element($xp, $elem, $attribs) { diff --git a/ext/xml/tests/xml009.phpt b/ext/xml/tests/xml009.phpt index 8986cebe607..12f7e0269b1 100644 --- a/ext/xml/tests/xml009.phpt +++ b/ext/xml/tests/xml009.phpt @@ -28,7 +28,6 @@ $parser = xml_parser_create_ns("ISO-8859-1","@"); xml_set_element_handler($parser,'start_elem','end_elem'); xml_parser_set_option($parser,XML_OPTION_CASE_FOLDING,0); xml_parse($parser, $xml); -xml_parser_free($parser); ?> --EXPECT-- string(24) "http://example.com/foo@a" diff --git a/ext/xml/tests/xml010.phpt b/ext/xml/tests/xml010.phpt index 7a1f33785bc..2ed5432efaf 100644 --- a/ext/xml/tests/xml010.phpt +++ b/ext/xml/tests/xml010.phpt @@ -32,7 +32,6 @@ $parser = xml_parser_create_ns("ISO-8859-1","@"); xml_set_element_handler($parser,'start_elem','end_elem'); xml_parser_set_option($parser,XML_OPTION_CASE_FOLDING,0); xml_parse($parser, $xml); -xml_parser_free($parser); ?> --EXPECT-- http://example.com/foo@a diff --git a/ext/xml/tests/xml011.phpt b/ext/xml/tests/xml011.phpt index f3557717e8f..d3e33fe326d 100644 --- a/ext/xml/tests/xml011.phpt +++ b/ext/xml/tests/xml011.phpt @@ -17,7 +17,6 @@ $xml = 'start This & that'; $parser = xml_parser_create(); xml_parse_into_struct($parser, $xml, $vals, $index); print_r($vals); -xml_parser_free($parser); echo "\nChange to empty end handler\n"; $parser = xml_parser_create(); @@ -26,7 +25,6 @@ xml_set_element_handler($parser,'start_elem','end_elem'); xml_set_element_handler($parser,'start_elem',NULL); xml_parse($parser, $xml, TRUE); -xml_parser_free($parser); echo "\nDone\n"; ?> --EXPECT-- diff --git a/ext/xml/tests/xml_closures_001.phpt b/ext/xml/tests/xml_closures_001.phpt index a6c65a2676c..119e7b51a7d 100644 --- a/ext/xml/tests/xml_closures_001.phpt +++ b/ext/xml/tests/xml_closures_001.phpt @@ -29,7 +29,6 @@ $fp = fopen("xmltest.xml", "r"); while ($data = fread($fp, 4096)) { xml_parse($xp, $data, feof($fp)); } -xml_parser_free($xp); ?> --EXPECT-- diff --git a/ext/xml/tests/xml_error_string_basic.inc b/ext/xml/tests/xml_error_string_basic.inc index e59bc411e57..ef9913d402d 100644 --- a/ext/xml/tests/xml_error_string_basic.inc +++ b/ext/xml/tests/xml_error_string_basic.inc @@ -13,5 +13,4 @@ foreach ($xmls as $xml) { var_dump(xml_get_error_code($xml_parser)); var_dump(xml_error_string(xml_get_error_code($xml_parser))); } - xml_parser_free($xml_parser); } \ No newline at end of file diff --git a/ext/xml/tests/xml_parse_into_struct_variation.phpt b/ext/xml/tests/xml_parse_into_struct_variation.phpt index 4571c4c73c5..a2067c937d0 100644 --- a/ext/xml/tests/xml_parse_into_struct_variation.phpt +++ b/ext/xml/tests/xml_parse_into_struct_variation.phpt @@ -9,7 +9,6 @@ echo "*** Testing xml_parse_into_struct() : variation ***\n"; $simple = "
simple notesimple note
"; $p = xml_parser_create(); xml_parse_into_struct($p, $simple, $vals, $index); -xml_parser_free($p); echo "Index array\n"; print_r($index); echo "\nVals array\n"; diff --git a/ext/xml/tests/xml_parser_free_deprecated.phpt b/ext/xml/tests/xml_parser_free_deprecated.phpt new file mode 100644 index 00000000000..0bb2583ac92 --- /dev/null +++ b/ext/xml/tests/xml_parser_free_deprecated.phpt @@ -0,0 +1,15 @@ +--TEST-- +xml_parser_free() deprecation message +--EXTENSIONS-- +xml +--FILE-- +',TRUE); +xml_parser_free($xp); +echo "Done\n"; +?> +--EXPECTF-- +Deprecated: Function xml_parser_free() is deprecated since 8.5, as it has no effect since PHP 8.0 in %s on line %d +Done diff --git a/ext/xml/tests/xml_parser_set_option_basic.phpt b/ext/xml/tests/xml_parser_set_option_basic.phpt index 2256775c93b..e93d78437b3 100644 --- a/ext/xml/tests/xml_parser_set_option_basic.phpt +++ b/ext/xml/tests/xml_parser_set_option_basic.phpt @@ -26,8 +26,6 @@ var_dump(xml_parser_get_option($parser, XML_OPTION_TARGET_ENCODING)); var_dump(xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, "US-ASCII")); var_dump(xml_parser_get_option($parser, XML_OPTION_TARGET_ENCODING)); -xml_parser_free( $parser ); - echo "Done\n"; ?> --EXPECT-- diff --git a/ext/xml/tests/xml_set_notation_decl_handler_basic.phpt b/ext/xml/tests/xml_set_notation_decl_handler_basic.phpt index ff2530cfead..2f50847d5be 100644 --- a/ext/xml/tests/xml_set_notation_decl_handler_basic.phpt +++ b/ext/xml/tests/xml_set_notation_decl_handler_basic.phpt @@ -32,7 +32,6 @@ class XML_Parser xml_set_notation_decl_handler($parser, $this->notation_decl_handler(...)); xml_set_unparsed_entity_decl_handler($parser, $this->unparsed_entity_decl_handler(...)); xml_parse($parser, $data, true); - xml_parser_free($parser); } } diff --git a/ext/xml/tests/xml_set_processing_instruction_handler_basic.phpt b/ext/xml/tests/xml_set_processing_instruction_handler_basic.phpt index 6041b2d44ee..57bbaba2085 100644 --- a/ext/xml/tests/xml_set_processing_instruction_handler_basic.phpt +++ b/ext/xml/tests/xml_set_processing_instruction_handler_basic.phpt @@ -18,7 +18,6 @@ class XML_Parser $parser = xml_parser_create(); xml_set_processing_instruction_handler($parser, $this->PIHandler(...)); xml_parse($parser, $data, true); - xml_parser_free($parser); } diff --git a/ext/xml/tests/xml_set_start_namespace_decl_handler_basic.inc b/ext/xml/tests/xml_set_start_namespace_decl_handler_basic.inc index b27b5c0efeb..9da9a1f3b6a 100644 --- a/ext/xml/tests/xml_set_start_namespace_decl_handler_basic.inc +++ b/ext/xml/tests/xml_set_start_namespace_decl_handler_basic.inc @@ -14,7 +14,6 @@ var_dump(xml_set_start_namespace_decl_handler( $parser, "Namespace_Start_Handler var_dump(xml_set_end_namespace_decl_handler( $parser, "Namespace_End_Handler" )); xml_parse( $parser, $xml, true); -xml_parser_free( $parser ); echo "Done\n"; diff --git a/ext/xml/xml.stub.php b/ext/xml/xml.stub.php index 54c286ff845..f589c3b2c8f 100644 --- a/ext/xml/xml.stub.php +++ b/ext/xml/xml.stub.php @@ -189,6 +189,7 @@ function xml_get_current_column_number(XMLParser $parser): int {} function xml_get_current_byte_index(XMLParser $parser): int {} +#[\Deprecated(since: '8.5', message: "as it has no effect since PHP 8.0")] function xml_parser_free(XMLParser $parser): bool {} /** @param string|int|bool $value */ diff --git a/ext/xml/xml_arginfo.h b/ext/xml/xml_arginfo.h index 61cad2c9d11..784424e7fd3 100644 --- a/ext/xml/xml_arginfo.h +++ b/ext/xml/xml_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 94b232499672dfd61c2c585a5d1d8a27d1a4a7ce */ + * Stub hash: c7838fb209d601be280dfdebfd135906afa36e8c */ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_xml_parser_create, 0, 0, XMLParser, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, encoding, IS_STRING, 1, "null") @@ -125,7 +125,7 @@ static const zend_function_entry ext_functions[] = { ZEND_FE(xml_get_current_line_number, arginfo_xml_get_current_line_number) ZEND_FE(xml_get_current_column_number, arginfo_xml_get_current_column_number) ZEND_FE(xml_get_current_byte_index, arginfo_xml_get_current_byte_index) - ZEND_FE(xml_parser_free, arginfo_xml_parser_free) + ZEND_RAW_FENTRY("xml_parser_free", zif_xml_parser_free, arginfo_xml_parser_free, ZEND_ACC_DEPRECATED, NULL, NULL) ZEND_FE(xml_parser_set_option, arginfo_xml_parser_set_option) ZEND_FE(xml_parser_get_option, arginfo_xml_parser_get_option) ZEND_FE_END @@ -166,11 +166,16 @@ static void register_xml_symbols(int module_number) zend_attribute *attribute_Deprecated_func_xml_set_object_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "xml_set_object", sizeof("xml_set_object") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_func_xml_set_object_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_4)); attribute_Deprecated_func_xml_set_object_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_xml_set_object_0_arg1; zend_string *attribute_Deprecated_func_xml_set_object_0_arg1_str = zend_string_init("provide a proper method callable to xml_set_*_handler() functions", strlen("provide a proper method callable to xml_set_*_handler() functions"), 1); - ZVAL_STR(&attribute_Deprecated_func_xml_set_object_0_arg1, attribute_Deprecated_func_xml_set_object_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_xml_set_object_0->args[1].value, &attribute_Deprecated_func_xml_set_object_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_xml_set_object_0->args[1].value, attribute_Deprecated_func_xml_set_object_0_arg1_str); attribute_Deprecated_func_xml_set_object_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + + zend_attribute *attribute_Deprecated_func_xml_parser_free_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "xml_parser_free", sizeof("xml_parser_free") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + ZVAL_STR(&attribute_Deprecated_func_xml_parser_free_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_5)); + attribute_Deprecated_func_xml_parser_free_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zend_string *attribute_Deprecated_func_xml_parser_free_0_arg1_str = zend_string_init("as it has no effect since PHP 8.0", strlen("as it has no effect since PHP 8.0"), 1); + ZVAL_STR(&attribute_Deprecated_func_xml_parser_free_0->args[1].value, attribute_Deprecated_func_xml_parser_free_0_arg1_str); + attribute_Deprecated_func_xml_parser_free_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); } static zend_class_entry *register_class_XMLParser(void) diff --git a/ext/xmlreader/tests/gh19098.phpt b/ext/xmlreader/tests/gh19098.phpt new file mode 100644 index 00000000000..13a6eda328f --- /dev/null +++ b/ext/xmlreader/tests/gh19098.phpt @@ -0,0 +1,44 @@ +--TEST-- +GH-19098 (libxml<2.13 segmentation fault caused by php_libxml_node_free) +--EXTENSIONS-- +xmlreader +dom +--FILE-- + + + + +'); + +$success = $xml_reader->next("sparql"); + +$success = $xml_reader->read(); +$success = $xml_reader->next("results"); + +while ($xml_reader->read()) { + if ($xml_reader->next("result")) { + $result_as_dom_node = $xml_reader->expand(); + $child = $result_as_dom_node->firstChild; + unset($result_as_dom_node); + var_dump($child->namespaceURI); + foreach ($child->attributes as $attr) { + var_dump($attr->namespaceURI); + } + $doc = new DOMDocument; + $doc->adoptNode($child); + echo $doc->saveXML($child), "\n"; + unset($child); + break; + } +} + +?> +--EXPECT-- +string(38) "http://www.w3.org/2005/sparql-results#" +string(36) "http://www.w3.org/XML/1998/namespace" +string(10) "urn:custom" +NULL + diff --git a/ext/xsl/xsltprocessor.c b/ext/xsl/xsltprocessor.c index ea0f9232ace..95e2e2e8754 100644 --- a/ext/xsl/xsltprocessor.c +++ b/ext/xsl/xsltprocessor.c @@ -609,7 +609,7 @@ PHP_METHOD(XSLTProcessor, setParameter) RETURN_THROWS(); } - if (UNEXPECTED(CHECK_NULL_PATH(ZSTR_VAL(string_key), ZSTR_LEN(string_key)))) { + if (UNEXPECTED(zend_str_has_nul_byte(string_key))) { zend_argument_value_error(3, "must not contain keys with any null bytes"); RETURN_THROWS(); } @@ -625,7 +625,7 @@ PHP_METHOD(XSLTProcessor, setParameter) RETURN_THROWS(); } - if (UNEXPECTED(CHECK_NULL_PATH(ZSTR_VAL(str), ZSTR_LEN(str)))) { + if (UNEXPECTED(zend_str_has_nul_byte(str))) { zend_string_release(str); zend_string_release_ex(ht_key, false); zend_argument_value_error(3, "must not contain values with any null bytes"); @@ -643,7 +643,7 @@ PHP_METHOD(XSLTProcessor, setParameter) RETURN_THROWS(); } - if (UNEXPECTED(CHECK_NULL_PATH(ZSTR_VAL(name), ZSTR_LEN(name)))) { + if (UNEXPECTED(zend_str_has_nul_byte(name))) { zend_argument_value_error(2, "must not contain any null bytes"); RETURN_THROWS(); } diff --git a/ext/zend_test/test.c b/ext/zend_test/test.c index 14aad0d1a32..c2e5ae6130e 100644 --- a/ext/zend_test/test.c +++ b/ext/zend_test/test.c @@ -14,6 +14,8 @@ +----------------------------------------------------------------------+ */ +#include "ext/opcache/zend_accelerator_api.h" +#include "zend_API.h" #include "zend_modules.h" #include "zend_types.h" #ifdef HAVE_CONFIG_H @@ -85,6 +87,13 @@ static ZEND_FUNCTION(zend_test_func) EX(func) = NULL; } +static ZEND_FUNCTION(zend_trigger_bailout) +{ + ZEND_PARSE_PARAMETERS_NONE(); + + zend_error(E_ERROR, "Bailout"); +} + static ZEND_FUNCTION(zend_test_array_return) { ZEND_PARSE_PARAMETERS_NONE(); @@ -514,6 +523,28 @@ static ZEND_FUNCTION(zend_object_init_with_constructor) ZVAL_COPY_VALUE(return_value, &obj); } +static ZEND_FUNCTION(zend_call_method_if_exists) +{ + zend_object *obj = NULL; + zend_string *method_name; + uint32_t num_args = 0; + zval *args = NULL; + ZEND_PARSE_PARAMETERS_START(2, -1) + Z_PARAM_OBJ(obj) + Z_PARAM_STR(method_name) + Z_PARAM_VARIADIC('*', args, num_args) + ZEND_PARSE_PARAMETERS_END(); + + zend_result status = zend_call_method_if_exists(obj, method_name, return_value, num_args, args); + if (status == FAILURE) { + ZEND_ASSERT(Z_ISUNDEF_P(return_value)); + if (EG(exception)) { + RETURN_THROWS(); + } + RETURN_NULL(); + } +} + static ZEND_FUNCTION(zend_get_unit_enum) { ZEND_PARSE_PARAMETERS_NONE(); @@ -1623,3 +1654,10 @@ static PHP_FUNCTION(zend_test_gh18756) zend_mm_gc(heap); zend_mm_shutdown(heap, true, false); } + +static PHP_FUNCTION(zend_test_opcache_preloading) +{ + ZEND_PARSE_PARAMETERS_NONE(); + + RETURN_BOOL(opcache_preloading()); +} diff --git a/ext/zend_test/test.stub.php b/ext/zend_test/test.stub.php index 528ec71ae7a..17316230e8d 100644 --- a/ext/zend_test/test.stub.php +++ b/ext/zend_test/test.stub.php @@ -208,6 +208,8 @@ namespace { case Baz = -1; } + function zend_trigger_bailout(): never {} + function zend_test_array_return(): array {} /** @genstubs-expose-comment-block @@ -293,6 +295,8 @@ namespace { function zend_object_init_with_constructor(string $class, mixed ...$args): mixed {} + function zend_call_method_if_exists(object $obj, string $method, mixed ...$args): mixed {} + function zend_test_zend_ini_parse_quantity(string $str): int {} function zend_test_zend_ini_parse_uquantity(string $str): int {} @@ -336,6 +340,8 @@ function zend_test_override_libxml_global_state(): void {} function zend_test_compile_to_ast(string $str): string {} function zend_test_gh18756(): void {} + + function zend_test_opcache_preloading(): bool {} } namespace ZendTestNS { diff --git a/ext/zend_test/test_arginfo.h b/ext/zend_test/test_arginfo.h index 07b519f3d6a..33c02310ba4 100644 --- a/ext/zend_test/test_arginfo.h +++ b/ext/zend_test/test_arginfo.h @@ -1,5 +1,8 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 13a5559e87cb073c921006bb3be5354b90247306 */ + * Stub hash: b767745e4e7be7cb4ba294e238a1b0f63da8479e */ + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_zend_trigger_bailout, 0, 0, IS_NEVER, 0) +ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_zend_test_array_return, 0, 0, IS_ARRAY, 0) ZEND_END_ARG_INFO() @@ -113,6 +116,12 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_zend_object_init_with_constructo ZEND_ARG_VARIADIC_TYPE_INFO(0, args, IS_MIXED, 0) ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_zend_call_method_if_exists, 0, 2, IS_MIXED, 0) + ZEND_ARG_TYPE_INFO(0, obj, IS_OBJECT, 0) + ZEND_ARG_TYPE_INFO(0, method, IS_STRING, 0) + ZEND_ARG_VARIADIC_TYPE_INFO(0, args, IS_MIXED, 0) +ZEND_END_ARG_INFO() + ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_zend_test_zend_ini_parse_quantity, 0, 1, IS_LONG, 0) ZEND_ARG_TYPE_INFO(0, str, IS_STRING, 0) ZEND_END_ARG_INFO() @@ -179,6 +188,8 @@ ZEND_END_ARG_INFO() #define arginfo_zend_test_gh18756 arginfo_zend_test_void_return +#define arginfo_zend_test_opcache_preloading arginfo_zend_test_is_pcre_bundled + #define arginfo_ZendTestNS2_namespaced_func arginfo_zend_test_is_pcre_bundled #define arginfo_ZendTestNS2_namespaced_deprecated_func arginfo_zend_test_void_return @@ -264,6 +275,7 @@ ZEND_END_ARG_INFO() #define arginfo_class_ZendTestNS2_ZendSubNS_Foo_method arginfo_zend_test_void_return +static ZEND_FUNCTION(zend_trigger_bailout); static ZEND_FUNCTION(zend_test_array_return); static ZEND_FUNCTION(zend_test_nullable_array_return); static ZEND_FUNCTION(zend_test_void_return); @@ -293,6 +305,7 @@ static ZEND_FUNCTION(zend_test_attribute_with_named_argument); static ZEND_FUNCTION(zend_get_current_func_name); static ZEND_FUNCTION(zend_call_method); static ZEND_FUNCTION(zend_object_init_with_constructor); +static ZEND_FUNCTION(zend_call_method_if_exists); static ZEND_FUNCTION(zend_test_zend_ini_parse_quantity); static ZEND_FUNCTION(zend_test_zend_ini_parse_uquantity); static ZEND_FUNCTION(zend_test_zend_ini_str); @@ -318,6 +331,7 @@ static ZEND_FUNCTION(zend_test_is_zend_ptr); static ZEND_FUNCTION(zend_test_log_err_debug); static ZEND_FUNCTION(zend_test_compile_to_ast); static ZEND_FUNCTION(zend_test_gh18756); +static ZEND_FUNCTION(zend_test_opcache_preloading); static ZEND_FUNCTION(ZendTestNS2_namespaced_func); static ZEND_FUNCTION(ZendTestNS2_namespaced_deprecated_func); static ZEND_FUNCTION(ZendTestNS2_ZendSubNS_namespaced_func); @@ -348,6 +362,7 @@ static ZEND_METHOD(ZendTestNS2_Foo, method); static ZEND_METHOD(ZendTestNS2_ZendSubNS_Foo, method); static const zend_function_entry ext_functions[] = { + ZEND_FE(zend_trigger_bailout, arginfo_zend_trigger_bailout) ZEND_FE(zend_test_array_return, arginfo_zend_test_array_return) #if (PHP_VERSION_ID >= 80400) ZEND_RAW_FENTRY("zend_test_nullable_array_return", zif_zend_test_nullable_array_return, arginfo_zend_test_nullable_array_return, ZEND_ACC_COMPILE_TIME_EVAL, NULL, "/**\n * \"Lorem ipsum\"\n * @see https://www.php.net\n * @since 8.3\n */") @@ -419,6 +434,7 @@ static const zend_function_entry ext_functions[] = { ZEND_FE(zend_get_current_func_name, arginfo_zend_get_current_func_name) ZEND_FE(zend_call_method, arginfo_zend_call_method) ZEND_FE(zend_object_init_with_constructor, arginfo_zend_object_init_with_constructor) + ZEND_FE(zend_call_method_if_exists, arginfo_zend_call_method_if_exists) ZEND_FE(zend_test_zend_ini_parse_quantity, arginfo_zend_test_zend_ini_parse_quantity) ZEND_FE(zend_test_zend_ini_parse_uquantity, arginfo_zend_test_zend_ini_parse_uquantity) ZEND_FE(zend_test_zend_ini_str, arginfo_zend_test_zend_ini_str) @@ -444,6 +460,7 @@ static const zend_function_entry ext_functions[] = { ZEND_FE(zend_test_log_err_debug, arginfo_zend_test_log_err_debug) ZEND_FE(zend_test_compile_to_ast, arginfo_zend_test_compile_to_ast) ZEND_FE(zend_test_gh18756, arginfo_zend_test_gh18756) + ZEND_FE(zend_test_opcache_preloading, arginfo_zend_test_opcache_preloading) #if (PHP_VERSION_ID >= 80400) ZEND_RAW_FENTRY(ZEND_NS_NAME("ZendTestNS2", "namespaced_func"), zif_ZendTestNS2_namespaced_func, arginfo_ZendTestNS2_namespaced_func, 0, NULL, NULL) #else @@ -591,69 +608,51 @@ static void register_test_symbols(int module_number) zend_string *attribute_name_Deprecated_func_zend_test_deprecated_attr_0 = zend_string_init_interned("Deprecated", sizeof("Deprecated") - 1, 1); zend_attribute *attribute_Deprecated_func_zend_test_deprecated_attr_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "zend_test_deprecated_attr", sizeof("zend_test_deprecated_attr") - 1), attribute_name_Deprecated_func_zend_test_deprecated_attr_0, 1); zend_string_release(attribute_name_Deprecated_func_zend_test_deprecated_attr_0); - zval attribute_Deprecated_func_zend_test_deprecated_attr_0_arg0; zend_string *attribute_Deprecated_func_zend_test_deprecated_attr_0_arg0_str = zend_string_init("custom message", strlen("custom message"), 1); - ZVAL_STR(&attribute_Deprecated_func_zend_test_deprecated_attr_0_arg0, attribute_Deprecated_func_zend_test_deprecated_attr_0_arg0_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_zend_test_deprecated_attr_0->args[0].value, &attribute_Deprecated_func_zend_test_deprecated_attr_0_arg0); + ZVAL_STR(&attribute_Deprecated_func_zend_test_deprecated_attr_0->args[0].value, attribute_Deprecated_func_zend_test_deprecated_attr_0_arg0_str); attribute_Deprecated_func_zend_test_deprecated_attr_0->args[0].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_string *attribute_name_NoDiscard_func_zend_test_nodiscard_0 = zend_string_init_interned("NoDiscard", sizeof("NoDiscard") - 1, 1); zend_attribute *attribute_NoDiscard_func_zend_test_nodiscard_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "zend_test_nodiscard", sizeof("zend_test_nodiscard") - 1), attribute_name_NoDiscard_func_zend_test_nodiscard_0, 1); zend_string_release(attribute_name_NoDiscard_func_zend_test_nodiscard_0); - zval attribute_NoDiscard_func_zend_test_nodiscard_0_arg0; - zend_string *attribute_NoDiscard_func_zend_test_nodiscard_0_arg0_str = zend_string_init("custom message", strlen("custom message"), 1); - ZVAL_STR(&attribute_NoDiscard_func_zend_test_nodiscard_0_arg0, attribute_NoDiscard_func_zend_test_nodiscard_0_arg0_str); - ZVAL_COPY_VALUE(&attribute_NoDiscard_func_zend_test_nodiscard_0->args[0].value, &attribute_NoDiscard_func_zend_test_nodiscard_0_arg0); + ZVAL_STR_COPY(&attribute_NoDiscard_func_zend_test_nodiscard_0->args[0].value, attribute_Deprecated_func_zend_test_deprecated_attr_0_arg0_str); attribute_NoDiscard_func_zend_test_nodiscard_0->args[0].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_string *attribute_name_Deprecated_func_zend_test_deprecated_nodiscard_0 = zend_string_init_interned("Deprecated", sizeof("Deprecated") - 1, 1); zend_attribute *attribute_Deprecated_func_zend_test_deprecated_nodiscard_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "zend_test_deprecated_nodiscard", sizeof("zend_test_deprecated_nodiscard") - 1), attribute_name_Deprecated_func_zend_test_deprecated_nodiscard_0, 1); zend_string_release(attribute_name_Deprecated_func_zend_test_deprecated_nodiscard_0); - zval attribute_Deprecated_func_zend_test_deprecated_nodiscard_0_arg0; - zend_string *attribute_Deprecated_func_zend_test_deprecated_nodiscard_0_arg0_str = zend_string_init("custom message", strlen("custom message"), 1); - ZVAL_STR(&attribute_Deprecated_func_zend_test_deprecated_nodiscard_0_arg0, attribute_Deprecated_func_zend_test_deprecated_nodiscard_0_arg0_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_zend_test_deprecated_nodiscard_0->args[0].value, &attribute_Deprecated_func_zend_test_deprecated_nodiscard_0_arg0); + ZVAL_STR_COPY(&attribute_Deprecated_func_zend_test_deprecated_nodiscard_0->args[0].value, attribute_Deprecated_func_zend_test_deprecated_attr_0_arg0_str); attribute_Deprecated_func_zend_test_deprecated_nodiscard_0->args[0].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_string *attribute_name_NoDiscard_func_zend_test_deprecated_nodiscard_1 = zend_string_init_interned("NoDiscard", sizeof("NoDiscard") - 1, 1); zend_attribute *attribute_NoDiscard_func_zend_test_deprecated_nodiscard_1 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "zend_test_deprecated_nodiscard", sizeof("zend_test_deprecated_nodiscard") - 1), attribute_name_NoDiscard_func_zend_test_deprecated_nodiscard_1, 1); zend_string_release(attribute_name_NoDiscard_func_zend_test_deprecated_nodiscard_1); - zval attribute_NoDiscard_func_zend_test_deprecated_nodiscard_1_arg0; zend_string *attribute_NoDiscard_func_zend_test_deprecated_nodiscard_1_arg0_str = zend_string_init("custom message 2", strlen("custom message 2"), 1); - ZVAL_STR(&attribute_NoDiscard_func_zend_test_deprecated_nodiscard_1_arg0, attribute_NoDiscard_func_zend_test_deprecated_nodiscard_1_arg0_str); - ZVAL_COPY_VALUE(&attribute_NoDiscard_func_zend_test_deprecated_nodiscard_1->args[0].value, &attribute_NoDiscard_func_zend_test_deprecated_nodiscard_1_arg0); + ZVAL_STR(&attribute_NoDiscard_func_zend_test_deprecated_nodiscard_1->args[0].value, attribute_NoDiscard_func_zend_test_deprecated_nodiscard_1_arg0_str); attribute_NoDiscard_func_zend_test_deprecated_nodiscard_1->args[0].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_string *attribute_name_ZendTestParameterAttribute_func_zend_test_parameter_with_attribute_arg0_0 = zend_string_init_interned("ZendTestParameterAttribute", sizeof("ZendTestParameterAttribute") - 1, 1); zend_attribute *attribute_ZendTestParameterAttribute_func_zend_test_parameter_with_attribute_arg0_0 = 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, attribute_name_ZendTestParameterAttribute_func_zend_test_parameter_with_attribute_arg0_0, 1); zend_string_release(attribute_name_ZendTestParameterAttribute_func_zend_test_parameter_with_attribute_arg0_0); - zval attribute_ZendTestParameterAttribute_func_zend_test_parameter_with_attribute_arg0_0_arg0; zend_string *attribute_ZendTestParameterAttribute_func_zend_test_parameter_with_attribute_arg0_0_arg0_str = zend_string_init("value1", strlen("value1"), 1); - ZVAL_STR(&attribute_ZendTestParameterAttribute_func_zend_test_parameter_with_attribute_arg0_0_arg0, attribute_ZendTestParameterAttribute_func_zend_test_parameter_with_attribute_arg0_0_arg0_str); - ZVAL_COPY_VALUE(&attribute_ZendTestParameterAttribute_func_zend_test_parameter_with_attribute_arg0_0->args[0].value, &attribute_ZendTestParameterAttribute_func_zend_test_parameter_with_attribute_arg0_0_arg0); + ZVAL_STR(&attribute_ZendTestParameterAttribute_func_zend_test_parameter_with_attribute_arg0_0->args[0].value, attribute_ZendTestParameterAttribute_func_zend_test_parameter_with_attribute_arg0_0_arg0_str); zend_string *attribute_name_ZendTestAttributeWithArguments_func_zend_test_attribute_with_named_argument_0 = zend_string_init_interned("ZendTestAttributeWithArguments", sizeof("ZendTestAttributeWithArguments") - 1, 1); zend_attribute *attribute_ZendTestAttributeWithArguments_func_zend_test_attribute_with_named_argument_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "zend_test_attribute_with_named_argument", sizeof("zend_test_attribute_with_named_argument") - 1), attribute_name_ZendTestAttributeWithArguments_func_zend_test_attribute_with_named_argument_0, 1); zend_string_release(attribute_name_ZendTestAttributeWithArguments_func_zend_test_attribute_with_named_argument_0); - zval attribute_ZendTestAttributeWithArguments_func_zend_test_attribute_with_named_argument_0_arg0; zend_string *attribute_ZendTestAttributeWithArguments_func_zend_test_attribute_with_named_argument_0_arg0_str = zend_string_init("foo", strlen("foo"), 1); - ZVAL_STR(&attribute_ZendTestAttributeWithArguments_func_zend_test_attribute_with_named_argument_0_arg0, attribute_ZendTestAttributeWithArguments_func_zend_test_attribute_with_named_argument_0_arg0_str); - ZVAL_COPY_VALUE(&attribute_ZendTestAttributeWithArguments_func_zend_test_attribute_with_named_argument_0->args[0].value, &attribute_ZendTestAttributeWithArguments_func_zend_test_attribute_with_named_argument_0_arg0); + ZVAL_STR(&attribute_ZendTestAttributeWithArguments_func_zend_test_attribute_with_named_argument_0->args[0].value, attribute_ZendTestAttributeWithArguments_func_zend_test_attribute_with_named_argument_0_arg0_str); attribute_ZendTestAttributeWithArguments_func_zend_test_attribute_with_named_argument_0->args[0].name = zend_string_init_interned("arg", sizeof("arg") - 1, 1); #if (PHP_VERSION_ID >= 80500) zend_constant *const_ZEND_TEST_ATTRIBUTED_CONSTANT = zend_hash_str_find_ptr(EG(zend_constants), "ZEND_TEST_ATTRIBUTED_CONSTANT", sizeof("ZEND_TEST_ATTRIBUTED_CONSTANT") - 1); zend_attribute *attribute_Deprecated_const_ZEND_TEST_ATTRIBUTED_CONSTANT_0 = zend_add_global_constant_attribute(const_ZEND_TEST_ATTRIBUTED_CONSTANT, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); - zval attribute_Deprecated_const_ZEND_TEST_ATTRIBUTED_CONSTANT_0_arg0; zend_string *attribute_Deprecated_const_ZEND_TEST_ATTRIBUTED_CONSTANT_0_arg0_str = zend_string_init("use something else", strlen("use something else"), 1); - ZVAL_STR(&attribute_Deprecated_const_ZEND_TEST_ATTRIBUTED_CONSTANT_0_arg0, attribute_Deprecated_const_ZEND_TEST_ATTRIBUTED_CONSTANT_0_arg0_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_const_ZEND_TEST_ATTRIBUTED_CONSTANT_0->args[0].value, &attribute_Deprecated_const_ZEND_TEST_ATTRIBUTED_CONSTANT_0_arg0); + ZVAL_STR(&attribute_Deprecated_const_ZEND_TEST_ATTRIBUTED_CONSTANT_0->args[0].value, attribute_Deprecated_const_ZEND_TEST_ATTRIBUTED_CONSTANT_0_arg0_str); attribute_Deprecated_const_ZEND_TEST_ATTRIBUTED_CONSTANT_0->args[0].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); - zval attribute_Deprecated_const_ZEND_TEST_ATTRIBUTED_CONSTANT_0_arg1; zend_string *attribute_Deprecated_const_ZEND_TEST_ATTRIBUTED_CONSTANT_0_arg1_str = zend_string_init("version 1.5", strlen("version 1.5"), 1); - ZVAL_STR(&attribute_Deprecated_const_ZEND_TEST_ATTRIBUTED_CONSTANT_0_arg1, attribute_Deprecated_const_ZEND_TEST_ATTRIBUTED_CONSTANT_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_const_ZEND_TEST_ATTRIBUTED_CONSTANT_0->args[1].value, &attribute_Deprecated_const_ZEND_TEST_ATTRIBUTED_CONSTANT_0_arg1); + ZVAL_STR(&attribute_Deprecated_const_ZEND_TEST_ATTRIBUTED_CONSTANT_0->args[1].value, attribute_Deprecated_const_ZEND_TEST_ATTRIBUTED_CONSTANT_0_arg1_str); attribute_Deprecated_const_ZEND_TEST_ATTRIBUTED_CONSTANT_0->args[1].name = ZSTR_KNOWN(ZEND_STR_SINCE); #endif } @@ -813,10 +812,8 @@ static zend_class_entry *register_class__ZendTestClass(zend_class_entry *class_e zend_string *attribute_name_Deprecated_const_ZEND_TEST_DEPRECATED_ATTR_0 = zend_string_init_interned("Deprecated", sizeof("Deprecated") - 1, 1); zend_attribute *attribute_Deprecated_const_ZEND_TEST_DEPRECATED_ATTR_0 = zend_add_class_constant_attribute(class_entry, const_ZEND_TEST_DEPRECATED_ATTR, attribute_name_Deprecated_const_ZEND_TEST_DEPRECATED_ATTR_0, 1); zend_string_release(attribute_name_Deprecated_const_ZEND_TEST_DEPRECATED_ATTR_0); - zval attribute_Deprecated_const_ZEND_TEST_DEPRECATED_ATTR_0_arg0; zend_string *attribute_Deprecated_const_ZEND_TEST_DEPRECATED_ATTR_0_arg0_str = zend_string_init("custom message", strlen("custom message"), 1); - ZVAL_STR(&attribute_Deprecated_const_ZEND_TEST_DEPRECATED_ATTR_0_arg0, attribute_Deprecated_const_ZEND_TEST_DEPRECATED_ATTR_0_arg0_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_const_ZEND_TEST_DEPRECATED_ATTR_0->args[0].value, &attribute_Deprecated_const_ZEND_TEST_DEPRECATED_ATTR_0_arg0); + ZVAL_STR(&attribute_Deprecated_const_ZEND_TEST_DEPRECATED_ATTR_0->args[0].value, attribute_Deprecated_const_ZEND_TEST_DEPRECATED_ATTR_0_arg0_str); attribute_Deprecated_const_ZEND_TEST_DEPRECATED_ATTR_0->args[0].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); return class_entry; @@ -923,10 +920,8 @@ static zend_class_entry *register_class_ZendAttributeTest(void) zend_string *attribute_name_ZendTestPropertyAttribute_property_testProp_1 = zend_string_init_interned("ZendTestPropertyAttribute", sizeof("ZendTestPropertyAttribute") - 1, 1); zend_attribute *attribute_ZendTestPropertyAttribute_property_testProp_1 = zend_add_property_attribute(class_entry, property_testProp, attribute_name_ZendTestPropertyAttribute_property_testProp_1, 1); zend_string_release(attribute_name_ZendTestPropertyAttribute_property_testProp_1); - zval attribute_ZendTestPropertyAttribute_property_testProp_1_arg0; zend_string *attribute_ZendTestPropertyAttribute_property_testProp_1_arg0_str = zend_string_init("testProp", strlen("testProp"), 1); - ZVAL_STR(&attribute_ZendTestPropertyAttribute_property_testProp_1_arg0, attribute_ZendTestPropertyAttribute_property_testProp_1_arg0_str); - ZVAL_COPY_VALUE(&attribute_ZendTestPropertyAttribute_property_testProp_1->args[0].value, &attribute_ZendTestPropertyAttribute_property_testProp_1_arg0); + ZVAL_STR(&attribute_ZendTestPropertyAttribute_property_testProp_1->args[0].value, attribute_ZendTestPropertyAttribute_property_testProp_1_arg0_str); zend_string *attribute_name_ZendTestAttribute_func_testmethod_0 = zend_string_init_interned("ZendTestAttribute", sizeof("ZendTestAttribute") - 1, 1); @@ -985,9 +980,7 @@ static zend_class_entry *register_class_ZendTestAttribute(void) zend_string *attribute_name_Attribute_class_ZendTestAttribute_0 = zend_string_init_interned("Attribute", sizeof("Attribute") - 1, 1); zend_attribute *attribute_Attribute_class_ZendTestAttribute_0 = zend_add_class_attribute(class_entry, attribute_name_Attribute_class_ZendTestAttribute_0, 1); zend_string_release(attribute_name_Attribute_class_ZendTestAttribute_0); - zval attribute_Attribute_class_ZendTestAttribute_0_arg0; - ZVAL_LONG(&attribute_Attribute_class_ZendTestAttribute_0_arg0, ZEND_ATTRIBUTE_TARGET_ALL); - ZVAL_COPY_VALUE(&attribute_Attribute_class_ZendTestAttribute_0->args[0].value, &attribute_Attribute_class_ZendTestAttribute_0_arg0); + ZVAL_LONG(&attribute_Attribute_class_ZendTestAttribute_0->args[0].value, ZEND_ATTRIBUTE_TARGET_ALL); return class_entry; } @@ -1017,9 +1010,7 @@ static zend_class_entry *register_class_ZendTestAttributeWithArguments(void) zend_string *attribute_name_Attribute_class_ZendTestAttributeWithArguments_0 = zend_string_init_interned("Attribute", sizeof("Attribute") - 1, 1); zend_attribute *attribute_Attribute_class_ZendTestAttributeWithArguments_0 = zend_add_class_attribute(class_entry, attribute_name_Attribute_class_ZendTestAttributeWithArguments_0, 1); zend_string_release(attribute_name_Attribute_class_ZendTestAttributeWithArguments_0); - zval attribute_Attribute_class_ZendTestAttributeWithArguments_0_arg0; - ZVAL_LONG(&attribute_Attribute_class_ZendTestAttributeWithArguments_0_arg0, ZEND_ATTRIBUTE_TARGET_ALL); - ZVAL_COPY_VALUE(&attribute_Attribute_class_ZendTestAttributeWithArguments_0->args[0].value, &attribute_Attribute_class_ZendTestAttributeWithArguments_0_arg0); + ZVAL_LONG(&attribute_Attribute_class_ZendTestAttributeWithArguments_0->args[0].value, ZEND_ATTRIBUTE_TARGET_ALL); return class_entry; } @@ -1039,9 +1030,7 @@ static zend_class_entry *register_class_ZendTestRepeatableAttribute(void) zend_string *attribute_name_Attribute_class_ZendTestRepeatableAttribute_0 = zend_string_init_interned("Attribute", sizeof("Attribute") - 1, 1); zend_attribute *attribute_Attribute_class_ZendTestRepeatableAttribute_0 = zend_add_class_attribute(class_entry, attribute_name_Attribute_class_ZendTestRepeatableAttribute_0, 1); zend_string_release(attribute_name_Attribute_class_ZendTestRepeatableAttribute_0); - zval attribute_Attribute_class_ZendTestRepeatableAttribute_0_arg0; - ZVAL_LONG(&attribute_Attribute_class_ZendTestRepeatableAttribute_0_arg0, ZEND_ATTRIBUTE_TARGET_ALL | ZEND_ATTRIBUTE_IS_REPEATABLE); - ZVAL_COPY_VALUE(&attribute_Attribute_class_ZendTestRepeatableAttribute_0->args[0].value, &attribute_Attribute_class_ZendTestRepeatableAttribute_0_arg0); + ZVAL_LONG(&attribute_Attribute_class_ZendTestRepeatableAttribute_0->args[0].value, ZEND_ATTRIBUTE_TARGET_ALL | ZEND_ATTRIBUTE_IS_REPEATABLE); return class_entry; } @@ -1067,9 +1056,7 @@ static zend_class_entry *register_class_ZendTestParameterAttribute(void) zend_string *attribute_name_Attribute_class_ZendTestParameterAttribute_0 = zend_string_init_interned("Attribute", sizeof("Attribute") - 1, 1); zend_attribute *attribute_Attribute_class_ZendTestParameterAttribute_0 = zend_add_class_attribute(class_entry, attribute_name_Attribute_class_ZendTestParameterAttribute_0, 1); zend_string_release(attribute_name_Attribute_class_ZendTestParameterAttribute_0); - zval attribute_Attribute_class_ZendTestParameterAttribute_0_arg0; - ZVAL_LONG(&attribute_Attribute_class_ZendTestParameterAttribute_0_arg0, ZEND_ATTRIBUTE_TARGET_PARAMETER); - ZVAL_COPY_VALUE(&attribute_Attribute_class_ZendTestParameterAttribute_0->args[0].value, &attribute_Attribute_class_ZendTestParameterAttribute_0_arg0); + ZVAL_LONG(&attribute_Attribute_class_ZendTestParameterAttribute_0->args[0].value, ZEND_ATTRIBUTE_TARGET_PARAMETER); return class_entry; } @@ -1099,9 +1086,7 @@ static zend_class_entry *register_class_ZendTestPropertyAttribute(void) zend_string *attribute_name_Attribute_class_ZendTestPropertyAttribute_0 = zend_string_init_interned("Attribute", sizeof("Attribute") - 1, 1); zend_attribute *attribute_Attribute_class_ZendTestPropertyAttribute_0 = zend_add_class_attribute(class_entry, attribute_name_Attribute_class_ZendTestPropertyAttribute_0, 1); zend_string_release(attribute_name_Attribute_class_ZendTestPropertyAttribute_0); - zval attribute_Attribute_class_ZendTestPropertyAttribute_0_arg0; - ZVAL_LONG(&attribute_Attribute_class_ZendTestPropertyAttribute_0_arg0, ZEND_ATTRIBUTE_TARGET_PROPERTY); - ZVAL_COPY_VALUE(&attribute_Attribute_class_ZendTestPropertyAttribute_0->args[0].value, &attribute_Attribute_class_ZendTestPropertyAttribute_0_arg0); + ZVAL_LONG(&attribute_Attribute_class_ZendTestPropertyAttribute_0->args[0].value, ZEND_ATTRIBUTE_TARGET_PROPERTY); return class_entry; } @@ -1121,18 +1106,14 @@ static zend_class_entry *register_class_ZendTestClassWithMethodWithParameterAttr zend_string *attribute_name_ZendTestParameterAttribute_func_no_override_arg0_0 = zend_string_init_interned("ZendTestParameterAttribute", sizeof("ZendTestParameterAttribute") - 1, 1); zend_attribute *attribute_ZendTestParameterAttribute_func_no_override_arg0_0 = zend_add_parameter_attribute(zend_hash_str_find_ptr(&class_entry->function_table, "no_override", sizeof("no_override") - 1), 0, attribute_name_ZendTestParameterAttribute_func_no_override_arg0_0, 1); zend_string_release(attribute_name_ZendTestParameterAttribute_func_no_override_arg0_0); - zval attribute_ZendTestParameterAttribute_func_no_override_arg0_0_arg0; zend_string *attribute_ZendTestParameterAttribute_func_no_override_arg0_0_arg0_str = zend_string_init("value2", strlen("value2"), 1); - ZVAL_STR(&attribute_ZendTestParameterAttribute_func_no_override_arg0_0_arg0, attribute_ZendTestParameterAttribute_func_no_override_arg0_0_arg0_str); - ZVAL_COPY_VALUE(&attribute_ZendTestParameterAttribute_func_no_override_arg0_0->args[0].value, &attribute_ZendTestParameterAttribute_func_no_override_arg0_0_arg0); + ZVAL_STR(&attribute_ZendTestParameterAttribute_func_no_override_arg0_0->args[0].value, attribute_ZendTestParameterAttribute_func_no_override_arg0_0_arg0_str); zend_string *attribute_name_ZendTestParameterAttribute_func_override_arg0_0 = zend_string_init_interned("ZendTestParameterAttribute", sizeof("ZendTestParameterAttribute") - 1, 1); zend_attribute *attribute_ZendTestParameterAttribute_func_override_arg0_0 = zend_add_parameter_attribute(zend_hash_str_find_ptr(&class_entry->function_table, "override", sizeof("override") - 1), 0, attribute_name_ZendTestParameterAttribute_func_override_arg0_0, 1); zend_string_release(attribute_name_ZendTestParameterAttribute_func_override_arg0_0); - zval attribute_ZendTestParameterAttribute_func_override_arg0_0_arg0; zend_string *attribute_ZendTestParameterAttribute_func_override_arg0_0_arg0_str = zend_string_init("value3", strlen("value3"), 1); - ZVAL_STR(&attribute_ZendTestParameterAttribute_func_override_arg0_0_arg0, attribute_ZendTestParameterAttribute_func_override_arg0_0_arg0_str); - ZVAL_COPY_VALUE(&attribute_ZendTestParameterAttribute_func_override_arg0_0->args[0].value, &attribute_ZendTestParameterAttribute_func_override_arg0_0_arg0); + ZVAL_STR(&attribute_ZendTestParameterAttribute_func_override_arg0_0->args[0].value, attribute_ZendTestParameterAttribute_func_override_arg0_0_arg0_str); return class_entry; } @@ -1152,10 +1133,8 @@ static zend_class_entry *register_class_ZendTestChildClassWithMethodWithParamete zend_string *attribute_name_ZendTestParameterAttribute_func_override_arg0_0 = zend_string_init_interned("ZendTestParameterAttribute", sizeof("ZendTestParameterAttribute") - 1, 1); zend_attribute *attribute_ZendTestParameterAttribute_func_override_arg0_0 = zend_add_parameter_attribute(zend_hash_str_find_ptr(&class_entry->function_table, "override", sizeof("override") - 1), 0, attribute_name_ZendTestParameterAttribute_func_override_arg0_0, 1); zend_string_release(attribute_name_ZendTestParameterAttribute_func_override_arg0_0); - zval attribute_ZendTestParameterAttribute_func_override_arg0_0_arg0; zend_string *attribute_ZendTestParameterAttribute_func_override_arg0_0_arg0_str = zend_string_init("value4", strlen("value4"), 1); - ZVAL_STR(&attribute_ZendTestParameterAttribute_func_override_arg0_0_arg0, attribute_ZendTestParameterAttribute_func_override_arg0_0_arg0_str); - ZVAL_COPY_VALUE(&attribute_ZendTestParameterAttribute_func_override_arg0_0->args[0].value, &attribute_ZendTestParameterAttribute_func_override_arg0_0_arg0); + ZVAL_STR(&attribute_ZendTestParameterAttribute_func_override_arg0_0->args[0].value, attribute_ZendTestParameterAttribute_func_override_arg0_0_arg0_str); return class_entry; } diff --git a/ext/zend_test/tests/gh9871.phpt b/ext/zend_test/tests/gh9871.phpt index b40a20a2609..d1a1be1a520 100644 --- a/ext/zend_test/tests/gh9871.phpt +++ b/ext/zend_test/tests/gh9871.phpt @@ -19,7 +19,7 @@ class A { } $property = new MyReflectionProperty('A', 'protected'); -$property->setAccessible(true); +$property->isStatic(); ?> --EXPECTF-- @@ -28,7 +28,7 @@ $property->setAccessible(true); - - - + + + diff --git a/ext/zend_test/tests/zend_call_method_if_exists/existing-non-public-methods.phpt b/ext/zend_test/tests/zend_call_method_if_exists/existing-non-public-methods.phpt new file mode 100644 index 00000000000..cb65aadcfbb --- /dev/null +++ b/ext/zend_test/tests/zend_call_method_if_exists/existing-non-public-methods.phpt @@ -0,0 +1,27 @@ +--TEST-- +zend_call_method_if_exists() with existing non public methods +--EXTENSIONS-- +zend_test +--FILE-- + +--EXPECT-- +NULL +NULL diff --git a/ext/zend_test/tests/zend_call_method_if_exists/existing-private-methods-within-scope.phpt b/ext/zend_test/tests/zend_call_method_if_exists/existing-private-methods-within-scope.phpt new file mode 100644 index 00000000000..a1677b353b2 --- /dev/null +++ b/ext/zend_test/tests/zend_call_method_if_exists/existing-private-methods-within-scope.phpt @@ -0,0 +1,23 @@ +--TEST-- +zend_call_method_if_exists() with existing public method +--EXTENSIONS-- +zend_test +--FILE-- +priv() + zend_call_method_if_exists($this, 'priv'); + } +} + +$c = new C(); +$c->test(); + +?> +--EXPECT-- +string(7) "C::priv" diff --git a/ext/zend_test/tests/zend_call_method_if_exists/existing-public-methods.phpt b/ext/zend_test/tests/zend_call_method_if_exists/existing-public-methods.phpt new file mode 100644 index 00000000000..c9bbd8cd13b --- /dev/null +++ b/ext/zend_test/tests/zend_call_method_if_exists/existing-public-methods.phpt @@ -0,0 +1,21 @@ +--TEST-- +zend_call_method_if_exists() with existing public method +--EXTENSIONS-- +zend_test +--FILE-- + +--EXPECT-- +string(6) "A::foo" diff --git a/ext/zend_test/tests/zend_call_method_if_exists/existing-static-non-public-methods.phpt b/ext/zend_test/tests/zend_call_method_if_exists/existing-static-non-public-methods.phpt new file mode 100644 index 00000000000..a08124a4420 --- /dev/null +++ b/ext/zend_test/tests/zend_call_method_if_exists/existing-static-non-public-methods.phpt @@ -0,0 +1,27 @@ +--TEST-- +zend_call_method_if_exists() with existing non public static methods +--EXTENSIONS-- +zend_test +--FILE-- + +--EXPECT-- +NULL +NULL diff --git a/ext/zend_test/tests/zend_call_method_if_exists/existing-static-public-methods.phpt b/ext/zend_test/tests/zend_call_method_if_exists/existing-static-public-methods.phpt new file mode 100644 index 00000000000..cc879a5b1aa --- /dev/null +++ b/ext/zend_test/tests/zend_call_method_if_exists/existing-static-public-methods.phpt @@ -0,0 +1,21 @@ +--TEST-- +zend_call_method_if_exists() with existing static public method +--EXTENSIONS-- +zend_test +--FILE-- + +--EXPECT-- +string(6) "A::foo" diff --git a/ext/zend_test/tests/zend_call_method_if_exists/extended-non-existing-method-with-trampoline.phpt b/ext/zend_test/tests/zend_call_method_if_exists/extended-non-existing-method-with-trampoline.phpt new file mode 100644 index 00000000000..fea9bc79028 --- /dev/null +++ b/ext/zend_test/tests/zend_call_method_if_exists/extended-non-existing-method-with-trampoline.phpt @@ -0,0 +1,27 @@ +--TEST-- +zend_call_method_if_exists() with non existing method on extended class with a trampoline +--EXTENSIONS-- +zend_test +--FILE-- + +--EXPECT-- +string(24) "In B trampoline for bar!" diff --git a/ext/zend_test/tests/zend_call_method_if_exists/extended-non-existing-method-with-trampoline2.phpt b/ext/zend_test/tests/zend_call_method_if_exists/extended-non-existing-method-with-trampoline2.phpt new file mode 100644 index 00000000000..41092d22521 --- /dev/null +++ b/ext/zend_test/tests/zend_call_method_if_exists/extended-non-existing-method-with-trampoline2.phpt @@ -0,0 +1,23 @@ +--TEST-- +zend_call_method_if_exists() with non existing method on extended class with a trampoline +--EXTENSIONS-- +zend_test +--FILE-- + +--EXPECT-- +string(24) "In A trampoline for bar!" diff --git a/ext/zend_test/tests/zend_call_method_if_exists/method-throws-exception.phpt b/ext/zend_test/tests/zend_call_method_if_exists/method-throws-exception.phpt new file mode 100644 index 00000000000..f70e160042b --- /dev/null +++ b/ext/zend_test/tests/zend_call_method_if_exists/method-throws-exception.phpt @@ -0,0 +1,25 @@ +--TEST-- +zend_call_method_if_exists() with throwing method +--EXTENSIONS-- +zend_test +--FILE-- +getMessage(), PHP_EOL; +} + +?> +--EXPECT-- +Exception: Error diff --git a/ext/zend_test/tests/zend_call_method_if_exists/non-existing-method-with-both-trampoline.phpt b/ext/zend_test/tests/zend_call_method_if_exists/non-existing-method-with-both-trampoline.phpt new file mode 100644 index 00000000000..d2f3d0fa30a --- /dev/null +++ b/ext/zend_test/tests/zend_call_method_if_exists/non-existing-method-with-both-trampoline.phpt @@ -0,0 +1,44 @@ +--TEST-- +zend_call_method_if_exists() with non existing method on class with a trampoline and static trampoline +--EXTENSIONS-- +zend_test +--FILE-- + +--EXPECT-- +string(24) "In A trampoline for bar!" +string(24) "In B trampoline for bar!" diff --git a/ext/zend_test/tests/zend_call_method_if_exists/non-existing-method-with-static-trampoline.phpt b/ext/zend_test/tests/zend_call_method_if_exists/non-existing-method-with-static-trampoline.phpt new file mode 100644 index 00000000000..3b111b14ea2 --- /dev/null +++ b/ext/zend_test/tests/zend_call_method_if_exists/non-existing-method-with-static-trampoline.phpt @@ -0,0 +1,24 @@ +--TEST-- +zend_call_method_if_exists() with non existing method on class with a static trampoline +--EXTENSIONS-- +zend_test +--FILE-- + +--EXPECT-- +NULL diff --git a/ext/zend_test/tests/zend_call_method_if_exists/non-existing-method-with-trampoline.phpt b/ext/zend_test/tests/zend_call_method_if_exists/non-existing-method-with-trampoline.phpt new file mode 100644 index 00000000000..335c1a2d00c --- /dev/null +++ b/ext/zend_test/tests/zend_call_method_if_exists/non-existing-method-with-trampoline.phpt @@ -0,0 +1,24 @@ +--TEST-- +zend_call_method_if_exists() with non existing method on class with a trampoline +--EXTENSIONS-- +zend_test +--FILE-- + +--EXPECT-- +string(22) "In trampoline for bar!" diff --git a/ext/zend_test/tests/zend_call_method_if_exists/non-existing-methods.phpt b/ext/zend_test/tests/zend_call_method_if_exists/non-existing-methods.phpt new file mode 100644 index 00000000000..2c570b35c81 --- /dev/null +++ b/ext/zend_test/tests/zend_call_method_if_exists/non-existing-methods.phpt @@ -0,0 +1,21 @@ +--TEST-- +zend_call_method_if_exists() with non existing method +--EXTENSIONS-- +zend_test +--FILE-- + +--EXPECT-- +NULL diff --git a/ext/zend_test/tests/zend_call_method_if_exists/shadowing-private-method-with-trampoline.phpt b/ext/zend_test/tests/zend_call_method_if_exists/shadowing-private-method-with-trampoline.phpt new file mode 100644 index 00000000000..459947c996e --- /dev/null +++ b/ext/zend_test/tests/zend_call_method_if_exists/shadowing-private-method-with-trampoline.phpt @@ -0,0 +1,24 @@ +--TEST-- +zend_call_method_if_exists() shadowing a private method +--EXTENSIONS-- +zend_test +--FILE-- + +--EXPECT-- +string(22) "In trampoline for foo!" diff --git a/ext/zend_test/tests/zend_call_method_if_exists/shadowing-private-method.phpt b/ext/zend_test/tests/zend_call_method_if_exists/shadowing-private-method.phpt new file mode 100644 index 00000000000..5f4e0ce222e --- /dev/null +++ b/ext/zend_test/tests/zend_call_method_if_exists/shadowing-private-method.phpt @@ -0,0 +1,27 @@ +--TEST-- +zend_call_method_if_exists() shadowing a private method +--EXTENSIONS-- +zend_test +--FILE-- + +--EXPECT-- +string(6) "B::foo" diff --git a/ext/zip/php_zip_arginfo.h b/ext/zip/php_zip_arginfo.h index 197204bbd49..2a24750142c 100644 --- a/ext/zip/php_zip_arginfo.h +++ b/ext/zip/php_zip_arginfo.h @@ -467,28 +467,22 @@ static void register_php_zip_symbols(int module_number) zend_attribute *attribute_Deprecated_func_zip_open_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "zip_open", sizeof("zip_open") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_func_zip_open_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_func_zip_open_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_zip_open_0_arg1; zend_string *attribute_Deprecated_func_zip_open_0_arg1_str = zend_string_init("use ZipArchive::open() instead", strlen("use ZipArchive::open() instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_zip_open_0_arg1, attribute_Deprecated_func_zip_open_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_zip_open_0->args[1].value, &attribute_Deprecated_func_zip_open_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_zip_open_0->args[1].value, attribute_Deprecated_func_zip_open_0_arg1_str); attribute_Deprecated_func_zip_open_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_func_zip_close_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "zip_close", sizeof("zip_close") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_func_zip_close_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_func_zip_close_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_zip_close_0_arg1; zend_string *attribute_Deprecated_func_zip_close_0_arg1_str = zend_string_init("use ZipArchive::close() instead", strlen("use ZipArchive::close() instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_zip_close_0_arg1, attribute_Deprecated_func_zip_close_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_zip_close_0->args[1].value, &attribute_Deprecated_func_zip_close_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_zip_close_0->args[1].value, attribute_Deprecated_func_zip_close_0_arg1_str); attribute_Deprecated_func_zip_close_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_func_zip_read_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "zip_read", sizeof("zip_read") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_func_zip_read_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_func_zip_read_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_zip_read_0_arg1; zend_string *attribute_Deprecated_func_zip_read_0_arg1_str = zend_string_init("use ZipArchive::statIndex() instead", strlen("use ZipArchive::statIndex() instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_zip_read_0_arg1, attribute_Deprecated_func_zip_read_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_zip_read_0->args[1].value, &attribute_Deprecated_func_zip_read_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_zip_read_0->args[1].value, attribute_Deprecated_func_zip_read_0_arg1_str); attribute_Deprecated_func_zip_read_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_func_zip_entry_open_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "zip_entry_open", sizeof("zip_entry_open") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 1); @@ -502,46 +496,32 @@ static void register_php_zip_symbols(int module_number) zend_attribute *attribute_Deprecated_func_zip_entry_read_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "zip_entry_read", sizeof("zip_entry_read") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_func_zip_entry_read_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_func_zip_entry_read_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_zip_entry_read_0_arg1; zend_string *attribute_Deprecated_func_zip_entry_read_0_arg1_str = zend_string_init("use ZipArchive::getFromIndex() instead", strlen("use ZipArchive::getFromIndex() instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_zip_entry_read_0_arg1, attribute_Deprecated_func_zip_entry_read_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_zip_entry_read_0->args[1].value, &attribute_Deprecated_func_zip_entry_read_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_zip_entry_read_0->args[1].value, attribute_Deprecated_func_zip_entry_read_0_arg1_str); attribute_Deprecated_func_zip_entry_read_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_func_zip_entry_name_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "zip_entry_name", sizeof("zip_entry_name") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_func_zip_entry_name_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_func_zip_entry_name_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_zip_entry_name_0_arg1; - zend_string *attribute_Deprecated_func_zip_entry_name_0_arg1_str = zend_string_init("use ZipArchive::statIndex() instead", strlen("use ZipArchive::statIndex() instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_zip_entry_name_0_arg1, attribute_Deprecated_func_zip_entry_name_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_zip_entry_name_0->args[1].value, &attribute_Deprecated_func_zip_entry_name_0_arg1); + ZVAL_STR_COPY(&attribute_Deprecated_func_zip_entry_name_0->args[1].value, attribute_Deprecated_func_zip_read_0_arg1_str); attribute_Deprecated_func_zip_entry_name_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_func_zip_entry_compressedsize_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "zip_entry_compressedsize", sizeof("zip_entry_compressedsize") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_func_zip_entry_compressedsize_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_func_zip_entry_compressedsize_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_zip_entry_compressedsize_0_arg1; - zend_string *attribute_Deprecated_func_zip_entry_compressedsize_0_arg1_str = zend_string_init("use ZipArchive::statIndex() instead", strlen("use ZipArchive::statIndex() instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_zip_entry_compressedsize_0_arg1, attribute_Deprecated_func_zip_entry_compressedsize_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_zip_entry_compressedsize_0->args[1].value, &attribute_Deprecated_func_zip_entry_compressedsize_0_arg1); + ZVAL_STR_COPY(&attribute_Deprecated_func_zip_entry_compressedsize_0->args[1].value, attribute_Deprecated_func_zip_read_0_arg1_str); attribute_Deprecated_func_zip_entry_compressedsize_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_func_zip_entry_filesize_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "zip_entry_filesize", sizeof("zip_entry_filesize") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_func_zip_entry_filesize_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_func_zip_entry_filesize_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_zip_entry_filesize_0_arg1; - zend_string *attribute_Deprecated_func_zip_entry_filesize_0_arg1_str = zend_string_init("use ZipArchive::statIndex() instead", strlen("use ZipArchive::statIndex() instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_zip_entry_filesize_0_arg1, attribute_Deprecated_func_zip_entry_filesize_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_zip_entry_filesize_0->args[1].value, &attribute_Deprecated_func_zip_entry_filesize_0_arg1); + ZVAL_STR_COPY(&attribute_Deprecated_func_zip_entry_filesize_0->args[1].value, attribute_Deprecated_func_zip_read_0_arg1_str); attribute_Deprecated_func_zip_entry_filesize_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_func_zip_entry_compressionmethod_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "zip_entry_compressionmethod", sizeof("zip_entry_compressionmethod") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); ZVAL_STR(&attribute_Deprecated_func_zip_entry_compressionmethod_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_func_zip_entry_compressionmethod_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_zip_entry_compressionmethod_0_arg1; - zend_string *attribute_Deprecated_func_zip_entry_compressionmethod_0_arg1_str = zend_string_init("use ZipArchive::statIndex() instead", strlen("use ZipArchive::statIndex() instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_zip_entry_compressionmethod_0_arg1, attribute_Deprecated_func_zip_entry_compressionmethod_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_zip_entry_compressionmethod_0->args[1].value, &attribute_Deprecated_func_zip_entry_compressionmethod_0_arg1); + ZVAL_STR_COPY(&attribute_Deprecated_func_zip_entry_compressionmethod_0->args[1].value, attribute_Deprecated_func_zip_read_0_arg1_str); attribute_Deprecated_func_zip_entry_compressionmethod_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); } diff --git a/ext/zip/tests/bug53603.phpt b/ext/zip/tests/bug53603.phpt index 54232062339..914b0b8440c 100644 --- a/ext/zip/tests/bug53603.phpt +++ b/ext/zip/tests/bug53603.phpt @@ -28,5 +28,5 @@ $a = $zip->extractTo('teststream://test'); var_dump($a); ?> --EXPECTF-- -Warning: ZipArchive::extractTo(teststream://test/foo): Failed to open stream: "TestStream::stream_open" call failed in %s on line %d +Warning: ZipArchive::extractTo(teststream://test/foo): Failed to open stream: "TestStream::stream_open" is not implemented in %s on line %d bool(false) diff --git a/main/SAPI.c b/main/SAPI.c index 866b44c3eac..169ae572fa9 100644 --- a/main/SAPI.c +++ b/main/SAPI.c @@ -597,7 +597,8 @@ static void sapi_update_response_code(int ncode) * since zend_llist_del_element only removes one matched item once, * we should remove them manually */ -static void sapi_remove_header(zend_llist *l, char *name, size_t len) { +static void sapi_remove_header(zend_llist *l, char *name, size_t len, size_t header_len) +{ sapi_header_struct *header; zend_llist_element *next; zend_llist_element *current=l->head; @@ -605,7 +606,8 @@ static void sapi_remove_header(zend_llist *l, char *name, size_t len) { while (current) { header = (sapi_header_struct *)(current->data); next = current->next; - if (header->header_len > len && header->header[len] == ':' + if (header->header_len > header_len + && (header->header[header_len] == ':' || len > header_len) && !strncasecmp(header->header, name, len)) { if (current->prev) { current->prev->next = next; @@ -653,7 +655,7 @@ static void sapi_header_add_op(sapi_header_op_enum op, sapi_header_struct *sapi_ char sav = *colon_offset; *colon_offset = 0; - sapi_remove_header(&SG(sapi_headers).headers, sapi_header->header, strlen(sapi_header->header)); + sapi_remove_header(&SG(sapi_headers).headers, sapi_header->header, strlen(sapi_header->header), 0); *colon_offset = sav; } } @@ -668,7 +670,7 @@ SAPI_API int sapi_header_op(sapi_header_op_enum op, void *arg) sapi_header_struct sapi_header; char *colon_offset; char *header_line; - size_t header_line_len; + size_t header_line_len, header_len; int http_response_code; if (SG(headers_sent) && !SG(request_info).no_headers) { @@ -691,6 +693,7 @@ SAPI_API int sapi_header_op(sapi_header_op_enum op, void *arg) case SAPI_HEADER_ADD: case SAPI_HEADER_REPLACE: + case SAPI_HEADER_DELETE_PREFIX: case SAPI_HEADER_DELETE: { sapi_header_line *p = arg; @@ -699,7 +702,13 @@ SAPI_API int sapi_header_op(sapi_header_op_enum op, void *arg) } header_line = estrndup(p->line, p->line_len); header_line_len = p->line_len; - http_response_code = p->response_code; + if (op == SAPI_HEADER_DELETE_PREFIX) { + header_len = p->header_len; + http_response_code = 0; + } else { + header_len = 0; + http_response_code = p->response_code; + } break; } @@ -722,8 +731,8 @@ SAPI_API int sapi_header_op(sapi_header_op_enum op, void *arg) header_line[header_line_len]='\0'; } - if (op == SAPI_HEADER_DELETE) { - if (strchr(header_line, ':')) { + if (op == SAPI_HEADER_DELETE || op == SAPI_HEADER_DELETE_PREFIX) { + if (op == SAPI_HEADER_DELETE && strchr(header_line, ':')) { efree(header_line); sapi_module.sapi_error(E_WARNING, "Header to delete may not contain colon."); return FAILURE; @@ -733,7 +742,7 @@ SAPI_API int sapi_header_op(sapi_header_op_enum op, void *arg) sapi_header.header_len = header_line_len; sapi_module.header_handler(&sapi_header, op, &SG(sapi_headers)); } - sapi_remove_header(&SG(sapi_headers).headers, header_line, header_line_len); + sapi_remove_header(&SG(sapi_headers).headers, header_line, header_line_len, header_len); efree(header_line); return SUCCESS; } else { diff --git a/main/SAPI.h b/main/SAPI.h index 284f4cb96f1..f7a64f24310 100644 --- a/main/SAPI.h +++ b/main/SAPI.h @@ -185,13 +185,17 @@ END_EXTERN_C() typedef struct { const char *line; /* If you allocated this, you need to free it yourself */ size_t line_len; - zend_long response_code; /* long due to zend_parse_parameters compatibility */ + union { + zend_long response_code; /* long due to zend_parse_parameters compatibility */ + size_t header_len; /* the "Key" in "Key: Value", for optimization */ + }; } sapi_header_line; typedef enum { /* Parameter: */ SAPI_HEADER_REPLACE, /* sapi_header_line* */ SAPI_HEADER_ADD, /* sapi_header_line* */ SAPI_HEADER_DELETE, /* sapi_header_line* */ + SAPI_HEADER_DELETE_PREFIX, /* sapi_header_line* */ SAPI_HEADER_DELETE_ALL, /* void */ SAPI_HEADER_SET_STATUS /* int */ } sapi_header_op_enum; @@ -199,7 +203,6 @@ typedef enum { /* Parameter: */ BEGIN_EXTERN_C() SAPI_API int sapi_header_op(sapi_header_op_enum op, void *arg); -/* Deprecated functions. Use sapi_header_op instead. */ SAPI_API int sapi_add_header_ex(const char *header_line, size_t header_line_len, bool duplicate, bool replace); #define sapi_add_header(a, b, c) sapi_add_header_ex((a),(b),(c),1) diff --git a/main/main.c b/main/main.c index 3518e4137ec..8465b6c09b1 100644 --- a/main/main.c +++ b/main/main.c @@ -51,6 +51,10 @@ #include "ext/date/php_date.h" #include "ext/random/php_random_csprng.h" #include "ext/random/php_random_zend_utils.h" +#include "ext/opcache/ZendAccelerator.h" +#ifdef HAVE_JIT +# include "ext/opcache/jit/zend_jit.h" +#endif #include "php_variables.h" #include "ext/standard/credits.h" #ifdef PHP_WIN32 @@ -332,6 +336,22 @@ static PHP_INI_MH(OnChangeMemoryLimit) } else { value = Z_L(1)<<30; /* effectively, no limit */ } + + /* If memory_limit exceeds max_memory_limit, warn and set to max_memory_limit instead. */ + if (value > PG(max_memory_limit)) { + if (value != -1) { + zend_error(E_WARNING, + "Failed to set memory_limit to %zd bytes. Setting to max_memory_limit instead (currently: " ZEND_LONG_FMT " bytes)", + value, PG(max_memory_limit)); + } + + zend_ini_entry *max_mem_limit_ini = zend_hash_str_find_ptr(EG(ini_directives), ZEND_STRL("max_memory_limit")); + entry->value = zend_string_copy(max_mem_limit_ini->value); + PG(memory_limit) = PG(max_memory_limit); + + return SUCCESS; + } + if (zend_set_memory_limit(value) == FAILURE) { /* When the memory limit is reset to the original level during deactivation, we may be * using more memory than the original limit while shutdown is still in progress. @@ -347,6 +367,26 @@ static PHP_INI_MH(OnChangeMemoryLimit) } /* }}} */ +static PHP_INI_MH(OnChangeMaxMemoryLimit) +{ + size_t value; + if (new_value) { + value = zend_ini_parse_uquantity_warn(new_value, entry->name); + } else { + value = Z_L(1) << 30; /* effectively, no limit */ + } + + if (zend_set_memory_limit(value) == FAILURE) { + zend_error(E_ERROR, "Failed to set memory limit to %zd bytes (Current memory usage is %zd bytes)", value, zend_memory_usage(true)); + return FAILURE; + } + + PG(memory_limit) = value; + PG(max_memory_limit) = value; + + return SUCCESS; +} + /* {{{ PHP_INI_MH */ static PHP_INI_MH(OnSetLogFilter) { @@ -707,7 +747,7 @@ static PHP_INI_MH(OnUpdateMailLog) static PHP_INI_MH(OnChangeMailForceExtra) { /* Check that INI setting does not have any nul bytes */ - if (new_value && ZSTR_LEN(new_value) != strlen(ZSTR_VAL(new_value))) { + if (new_value && zend_str_has_nul_byte(new_value)) { /* TODO Emit warning? */ return FAILURE; } @@ -810,7 +850,10 @@ PHP_INI_BEGIN() STD_PHP_INI_BOOLEAN("mail.mixed_lf_and_crlf", "0", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateBool, mail_mixed_lf_and_crlf, php_core_globals, core_globals) STD_PHP_INI_ENTRY("mail.log", NULL, PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateMailLog, mail_log, php_core_globals, core_globals) PHP_INI_ENTRY("browscap", NULL, PHP_INI_SYSTEM, OnChangeBrowscap) - PHP_INI_ENTRY("memory_limit", "128M", PHP_INI_ALL, OnChangeMemoryLimit) + + PHP_INI_ENTRY("max_memory_limit", "-1", PHP_INI_SYSTEM, OnChangeMaxMemoryLimit) + PHP_INI_ENTRY("memory_limit", "128M", PHP_INI_ALL, OnChangeMemoryLimit) + PHP_INI_ENTRY("precision", "14", PHP_INI_ALL, OnSetPrecision) PHP_INI_ENTRY("sendmail_from", NULL, PHP_INI_ALL, NULL) PHP_INI_ENTRY("sendmail_path", DEFAULT_SENDMAIL_PATH, PHP_INI_SYSTEM, NULL) @@ -1010,7 +1053,7 @@ PHPAPI ZEND_COLD void php_verror(const char *docref, const char *params, int typ const char *space = ""; const char *class_name = ""; const char *function; - int origin_len; + size_t origin_len; char *origin; zend_string *message; int is_function = 0; @@ -1077,9 +1120,10 @@ PHPAPI ZEND_COLD void php_verror(const char *docref, const char *params, int typ /* if we still have memory then format the origin */ if (is_function) { - origin_len = (int)spprintf(&origin, 0, "%s%s%s(%s)", class_name, space, function, params); + origin_len = spprintf(&origin, 0, "%s%s%s(%s)", class_name, space, function, params); } else { - origin_len = (int)spprintf(&origin, 0, "%s", function); + origin_len = strlen(function); + origin = estrndup(function, origin_len); } if (PG(html_errors)) { @@ -1096,14 +1140,14 @@ PHPAPI ZEND_COLD void php_verror(const char *docref, const char *params, int typ /* no docref given but function is known (the default) */ if (!docref && is_function) { - int doclen; + size_t doclen; while (*function == '_') { function++; } if (space[0] == '\0') { - doclen = (int)spprintf(&docref_buf, 0, "function.%s", function); + doclen = spprintf(&docref_buf, 0, "function.%s", function); } else { - doclen = (int)spprintf(&docref_buf, 0, "%s.%s", class_name, function); + doclen = spprintf(&docref_buf, 0, "%s.%s", class_name, function); } while((p = strchr(docref_buf, '_')) != NULL) { *p = '-'; @@ -1577,24 +1621,16 @@ try_again: PHP_FUNCTION(set_time_limit) { zend_long new_timeout; - char *new_timeout_str; - size_t new_timeout_strlen; - zend_string *key; if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &new_timeout) == FAILURE) { RETURN_THROWS(); } - new_timeout_strlen = zend_spprintf(&new_timeout_str, 0, ZEND_LONG_FMT, new_timeout); - - key = ZSTR_INIT_LITERAL("max_execution_time", 0); - if (zend_alter_ini_entry_chars_ex(key, new_timeout_str, new_timeout_strlen, PHP_INI_USER, PHP_INI_STAGE_RUNTIME, 0) == SUCCESS) { - RETVAL_TRUE; - } else { - RETVAL_FALSE; - } - zend_string_release_ex(key, 0); - efree(new_timeout_str); + zend_string *time = zend_long_to_str(new_timeout); + zend_string *key = ZSTR_INIT_LITERAL("max_execution_time", false); + RETVAL_BOOL(zend_alter_ini_entry_ex(key, time, PHP_INI_USER, PHP_INI_STAGE_RUNTIME, false) == SUCCESS); + zend_string_release_ex(key, false); + zend_string_release_ex(time, false); } /* }}} */ @@ -1816,6 +1852,12 @@ static void sigchld_handler(int apar) /* }}} */ #endif +PHPAPI void php_child_init(void) +{ + refresh_memory_manager(); + zend_max_execution_timer_init(); +} + /* {{{ php_request_startup */ zend_result php_request_startup(void) { @@ -2236,9 +2278,7 @@ zend_result php_module_startup(sapi_module_struct *sf, zend_module_entry *additi load zend extensions and register php function extensions to be loaded later */ zend_stream_init(); - if (php_init_config() == FAILURE) { - return FAILURE; - } + php_init_config(); zend_stream_shutdown(); /* Register PHP core ini entries */ @@ -2767,7 +2807,12 @@ PHPAPI void php_reserve_tsrm_memory(void) TSRM_ALIGNED_SIZE(zend_mm_globals_size()) + TSRM_ALIGNED_SIZE(zend_gc_globals_size()) + TSRM_ALIGNED_SIZE(sizeof(php_core_globals)) + - TSRM_ALIGNED_SIZE(sizeof(sapi_globals_struct)) + TSRM_ALIGNED_SIZE(sizeof(sapi_globals_struct)) + + TSRM_ALIGNED_SIZE(sizeof(zend_accel_globals)) + +#ifdef HAVE_JIT + TSRM_ALIGNED_SIZE(sizeof(zend_jit_globals)) + +#endif + 0 ); } /* }}} */ diff --git a/main/main.stub.php b/main/main.stub.php index 3359d4a1cd0..2732ccd290f 100644 --- a/main/main.stub.php +++ b/main/main.stub.php @@ -41,6 +41,14 @@ const PHP_VERSION_ID = UNKNOWN; */ const PHP_BUILD_DATE = UNKNOWN; +#ifdef PHP_BUILD_PROVIDER +/** + * @var string + * @cvalue PHP_BUILD_PROVIDER + */ +const PHP_BUILD_PROVIDER = UNKNOWN; +#endif + /** * @var bool * @cvalue PHP_ZTS diff --git a/main/main_arginfo.h b/main/main_arginfo.h index 922af3aff06..3aa0b07e42c 100644 --- a/main/main_arginfo.h +++ b/main/main_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: cb5c9a3e48b18a773264378099267550ca9e4fc1 */ + * Stub hash: e8b81aa6f03d36f35def2bb1fcc3563b284a113b */ static void register_main_symbols(int module_number) { @@ -10,6 +10,9 @@ static void register_main_symbols(int module_number) REGISTER_STRING_CONSTANT("PHP_EXTRA_VERSION", PHP_EXTRA_VERSION, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("PHP_VERSION_ID", PHP_VERSION_ID, CONST_PERSISTENT); REGISTER_STRING_CONSTANT("PHP_BUILD_DATE", php_build_date, CONST_PERSISTENT); +#if defined(PHP_BUILD_PROVIDER) + REGISTER_STRING_CONSTANT("PHP_BUILD_PROVIDER", PHP_BUILD_PROVIDER, CONST_PERSISTENT); +#endif REGISTER_BOOL_CONSTANT("PHP_ZTS", PHP_ZTS, CONST_PERSISTENT); REGISTER_BOOL_CONSTANT("PHP_DEBUG", PHP_DEBUG, CONST_PERSISTENT); REGISTER_STRING_CONSTANT("PHP_OS", PHP_OS_STR, CONST_PERSISTENT); diff --git a/main/network.c b/main/network.c index 14f4ca4dff9..70dc5055828 100644 --- a/main/network.c +++ b/main/network.c @@ -1109,7 +1109,7 @@ PHPAPI php_stream *_php_stream_sock_open_from_socket(php_socket_t socket, const sock = pemalloc(sizeof(php_netstream_data_t), persistent_id ? 1 : 0); memset(sock, 0, sizeof(php_netstream_data_t)); - sock->is_blocked = 1; + sock->is_blocked = true; sock->timeout.tv_sec = FG(default_socket_timeout); sock->timeout.tv_usec = 0; sock->socket = socket; diff --git a/main/php_globals.h b/main/php_globals.h index ab7a9a00b2f..94e5aa44fc5 100644 --- a/main/php_globals.h +++ b/main/php_globals.h @@ -72,6 +72,7 @@ struct _php_core_globals { zend_long serialize_precision; zend_long memory_limit; + zend_long max_memory_limit; zend_long max_input_time; char *error_log; diff --git a/main/php_ini.c b/main/php_ini.c index 8d0fdfdf72d..e464c05d1fc 100644 --- a/main/php_ini.c +++ b/main/php_ini.c @@ -21,7 +21,6 @@ #include "php_ini.h" #include "ext/standard/dl.h" #include "zend_extensions.h" -#include "zend_highlight.h" #include "SAPI.h" #include "php_main.h" #include "php_scandir.h" @@ -49,17 +48,17 @@ #endif -typedef struct _php_extension_lists { +typedef struct php_extension_lists { zend_llist engine; zend_llist functions; } php_extension_lists; /* True globals */ -static int is_special_section = 0; +static bool is_special_section = false; static HashTable *active_ini_hash; static HashTable configuration_hash; -static int has_per_dir_config = 0; -static int has_per_host_config = 0; +static bool has_per_dir_config = false; +static bool has_per_host_config = false; PHPAPI char *php_ini_opened_path=NULL; static php_extension_lists extension_lists; PHPAPI char *php_ini_scanned_path=NULL; @@ -175,7 +174,7 @@ PHPAPI void config_zval_dtor(zval *zvalue) /* Reset / free active_ini_section global */ #define RESET_ACTIVE_INI_HASH() do { \ active_ini_hash = NULL; \ - is_special_section = 0; \ + is_special_section = false; \ } while (0) /* }}} */ @@ -211,7 +210,7 @@ static void php_ini_parser_cb(zval *arg1, zval *arg2, zval *arg3, int callback_t } else { /* Store in active hash */ entry = zend_hash_update(active_hash, Z_STR_P(arg1), arg2); - Z_STR_P(entry) = zend_string_dup(Z_STR_P(entry), 1); + Z_STR_P(entry) = zend_string_dup(Z_STR_P(entry), true); } } break; @@ -230,7 +229,7 @@ static void php_ini_parser_cb(zval *arg1, zval *arg2, zval *arg3, int callback_t /* If option not found in hash or is not an array -> create array, otherwise add to existing array */ if ((find_arr = zend_hash_find(active_hash, Z_STR_P(arg1))) == NULL || Z_TYPE_P(find_arr) != IS_ARRAY) { ZVAL_NEW_PERSISTENT_ARR(&option_arr); - zend_hash_init(Z_ARRVAL(option_arr), 8, NULL, config_zval_dtor, 1); + zend_hash_init(Z_ARRVAL(option_arr), 8, NULL, config_zval_dtor, true); find_arr = zend_hash_update(active_hash, Z_STR_P(arg1), &option_arr); } @@ -240,7 +239,7 @@ static void php_ini_parser_cb(zval *arg1, zval *arg2, zval *arg3, int callback_t } else { entry = zend_hash_next_index_insert(Z_ARRVAL_P(find_arr), arg2); } - Z_STR_P(entry) = zend_string_dup(Z_STR_P(entry), 1); + Z_STR_P(entry) = zend_string_dup(Z_STR_P(entry), true); } break; @@ -252,27 +251,27 @@ static void php_ini_parser_cb(zval *arg1, zval *arg2, zval *arg3, int callback_t size_t key_len; /* PATH sections */ - if (!zend_binary_strncasecmp(Z_STRVAL_P(arg1), Z_STRLEN_P(arg1), "PATH", sizeof("PATH") - 1, sizeof("PATH") - 1)) { + if (zend_string_starts_with_literal_ci(Z_STR_P(arg1), "PATH")) { key = Z_STRVAL_P(arg1); key = key + sizeof("PATH") - 1; key_len = Z_STRLEN_P(arg1) - sizeof("PATH") + 1; - is_special_section = 1; - has_per_dir_config = 1; + is_special_section = true; + has_per_dir_config = true; /* make the path lowercase on Windows, for case insensitivity. Does nothing for other platforms */ TRANSLATE_SLASHES_LOWER(key); /* HOST sections */ - } else if (!zend_binary_strncasecmp(Z_STRVAL_P(arg1), Z_STRLEN_P(arg1), "HOST", sizeof("HOST") - 1, sizeof("HOST") - 1)) { + } else if (zend_string_starts_with_literal_ci(Z_STR_P(arg1), "HOST")) { key = Z_STRVAL_P(arg1); key = key + sizeof("HOST") - 1; key_len = Z_STRLEN_P(arg1) - sizeof("HOST") + 1; - is_special_section = 1; - has_per_host_config = 1; + is_special_section = true; + has_per_host_config = true; zend_str_tolower(key, key_len); /* host names are case-insensitive. */ } else { - is_special_section = 0; + is_special_section = false; } if (key && key_len > 0) { @@ -297,7 +296,7 @@ static void php_ini_parser_cb(zval *arg1, zval *arg2, zval *arg3, int callback_t zval section_arr; ZVAL_NEW_PERSISTENT_ARR(§ion_arr); - zend_hash_init(Z_ARRVAL(section_arr), 8, NULL, (dtor_func_t) config_zval_dtor, 1); + zend_hash_init(Z_ARRVAL(section_arr), 8, NULL, (dtor_func_t) config_zval_dtor, true); entry = zend_hash_str_update(target_hash, key, key_len, §ion_arr); } if (Z_TYPE_P(entry) == IS_ARRAY) { @@ -407,30 +406,30 @@ static void append_ini_path(char *php_ini_search_path, size_t search_path_size, } /* {{{ php_init_config */ -int php_init_config(void) +void php_init_config(void) { char *php_ini_file_name = NULL; char *php_ini_search_path = NULL; - int php_ini_scanned_path_len; + size_t php_ini_scanned_path_len; char *open_basedir; - int free_ini_search_path = 0; + bool free_ini_search_path = false; zend_string *opened_path = NULL; - zend_hash_init(&configuration_hash, 8, NULL, config_zval_dtor, 1); + zend_hash_init(&configuration_hash, 8, NULL, config_zval_dtor, true); if (sapi_module.ini_defaults) { sapi_module.ini_defaults(&configuration_hash); } - zend_llist_init(&extension_lists.engine, sizeof(char *), (llist_dtor_func_t) free_estring, 1); - zend_llist_init(&extension_lists.functions, sizeof(char *), (llist_dtor_func_t) free_estring, 1); + zend_llist_init(&extension_lists.engine, sizeof(char *), (llist_dtor_func_t) free_estring, true); + zend_llist_init(&extension_lists.functions, sizeof(char *), (llist_dtor_func_t) free_estring, true); open_basedir = PG(open_basedir); if (sapi_module.php_ini_path_override) { php_ini_file_name = sapi_module.php_ini_path_override; php_ini_search_path = sapi_module.php_ini_path_override; - free_ini_search_path = 0; + free_ini_search_path = false; } else if (!sapi_module.php_ini_ignore) { size_t search_path_size; char *default_location; @@ -480,7 +479,7 @@ int php_init_config(void) search_path_size = MAXPATHLEN * 4 + strlen(env_location) + 3 + 1; php_ini_search_path = (char *) emalloc(search_path_size); - free_ini_search_path = 1; + free_ini_search_path = true; php_ini_search_path[0] = 0; /* Add environment location */ @@ -601,15 +600,15 @@ int php_init_config(void) zend_stream_init_fp(&fh, fp, filename); RESET_ACTIVE_INI_HASH(); - zend_parse_ini_file(&fh, 1, ZEND_INI_SCANNER_NORMAL, (zend_ini_parser_cb_t) php_ini_parser_cb, &configuration_hash); + zend_parse_ini_file(&fh, true, ZEND_INI_SCANNER_NORMAL, (zend_ini_parser_cb_t) php_ini_parser_cb, &configuration_hash); { zval tmp; - ZVAL_NEW_STR(&tmp, zend_string_init(filename, strlen(filename), 1)); + ZVAL_NEW_STR(&tmp, zend_string_init(filename, strlen(filename), true)); zend_hash_str_update(&configuration_hash, "cfg_file_path", sizeof("cfg_file_path")-1, &tmp); if (opened_path) { - zend_string_release_ex(opened_path, 0); + zend_string_release_ex(opened_path, false); } php_ini_opened_path = zend_strndup(Z_STRVAL(tmp), Z_STRLEN(tmp)); } @@ -626,22 +625,20 @@ int php_init_config(void) /* Or fall back using possible --with-config-file-scan-dir setting (defaults to empty string!) */ php_ini_scanned_path = PHP_CONFIG_FILE_SCAN_DIR; } - php_ini_scanned_path_len = (int)strlen(php_ini_scanned_path); + php_ini_scanned_path_len = strlen(php_ini_scanned_path); /* Scan and parse any .ini files found in scan path if path not empty. */ if (!sapi_module.php_ini_ignore && php_ini_scanned_path_len) { struct dirent **namelist; - int ndir, i; zend_stat_t sb = {0}; char ini_file[MAXPATHLEN]; char *p; zend_llist scanned_ini_list; - zend_llist_element *element; - int l, total_l = 0; + size_t total_l = 0; char *bufpath, *debpath, *endpath; - int lenpath; + size_t lenpath; - zend_llist_init(&scanned_ini_list, sizeof(char *), (llist_dtor_func_t) free_estring, 1); + zend_llist_init(&scanned_ini_list, sizeof(char *), (llist_dtor_func_t) free_estring, true); bufpath = estrdup(php_ini_scanned_path); for (debpath = bufpath ; debpath ; debpath=endpath) { @@ -654,11 +651,11 @@ int php_init_config(void) to allow "/foo/php.d:" or ":/foo/php.d" */ debpath = PHP_CONFIG_FILE_SCAN_DIR; } - lenpath = (int)strlen(debpath); + lenpath = strlen(debpath); - if (lenpath > 0 && (ndir = php_scandir(debpath, &namelist, 0, php_alphasort)) > 0) { - - for (i = 0; i < ndir; i++) { + int ndir; + if (lenpath > 0 && (ndir = php_scandir(debpath, &namelist, NULL, php_alphasort)) > 0) { + for (int i = 0; i < ndir; i++) { /* check for any file with .ini extension */ if (!(p = strrchr(namelist[i]->d_name, '.')) || (p && strcmp(p, ".ini"))) { @@ -679,9 +676,9 @@ int php_init_config(void) 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) { + if (zend_parse_ini_file(&fh, true, 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); + size_t l = strlen(ini_file); total_l += l + 2; p = estrndup(ini_file, l); zend_llist_add_element(&scanned_ini_list, &p); @@ -698,13 +695,13 @@ int php_init_config(void) efree(bufpath); if (total_l) { - int php_ini_scanned_files_len = (php_ini_scanned_files) ? (int)strlen(php_ini_scanned_files) + 1 : 0; + size_t php_ini_scanned_files_len = (php_ini_scanned_files) ? strlen(php_ini_scanned_files) + 1 : 0; php_ini_scanned_files = (char *) realloc(php_ini_scanned_files, php_ini_scanned_files_len + total_l + 1); if (!php_ini_scanned_files_len) { *php_ini_scanned_files = '\0'; } total_l += php_ini_scanned_files_len; - for (element = scanned_ini_list.head; element; element = element->next) { + for (zend_llist_element *element = scanned_ini_list.head; element; element = element->next) { if (php_ini_scanned_files_len) { strlcat(php_ini_scanned_files, ",\n", total_l); } @@ -721,15 +718,13 @@ int php_init_config(void) if (sapi_module.ini_entries) { /* Reset active ini section */ RESET_ACTIVE_INI_HASH(); - zend_parse_ini_string(sapi_module.ini_entries, 1, ZEND_INI_SCANNER_NORMAL, (zend_ini_parser_cb_t) php_ini_parser_cb, &configuration_hash); + zend_parse_ini_string(sapi_module.ini_entries, true, ZEND_INI_SCANNER_NORMAL, (zend_ini_parser_cb_t) php_ini_parser_cb, &configuration_hash); } - - return SUCCESS; } /* }}} */ /* {{{ php_shutdown_config */ -int php_shutdown_config(void) +void php_shutdown_config(void) { zend_hash_destroy(&configuration_hash); if (php_ini_opened_path) { @@ -740,7 +735,6 @@ int php_shutdown_config(void) free(php_ini_scanned_files); php_ini_scanned_files = NULL; } - return SUCCESS; } /* }}} */ @@ -756,7 +750,7 @@ void php_ini_register_extensions(void) /* }}} */ /* {{{ php_parse_user_ini_file */ -PHPAPI int php_parse_user_ini_file(const char *dirname, const char *ini_filename, HashTable *target_hash) +PHPAPI zend_result php_parse_user_ini_file(const char *dirname, const char *ini_filename, HashTable *target_hash) { zend_stat_t sb = {0}; char ini_file[MAXPATHLEN]; @@ -766,7 +760,7 @@ PHPAPI int php_parse_user_ini_file(const char *dirname, const char *ini_filename if (VCWD_STAT(ini_file, &sb) == 0) { if (S_ISREG(sb.st_mode)) { zend_file_handle fh; - int ret = FAILURE; + zend_result ret = FAILURE; zend_stream_init_fp(&fh, VCWD_FOPEN(ini_file, "r"), ini_file); if (fh.handle.fp) { @@ -780,7 +774,7 @@ PHPAPI int php_parse_user_ini_file(const char *dirname, const char *ini_filename bool orig_rc_debug = zend_rc_debug; zend_rc_debug = false; #endif - ret = zend_parse_ini_file(&fh, 1, ZEND_INI_SCANNER_NORMAL, (zend_ini_parser_cb_t) php_ini_parser_cb, target_hash); + ret = zend_parse_ini_file(&fh, true, ZEND_INI_SCANNER_NORMAL, (zend_ini_parser_cb_t) php_ini_parser_cb, target_hash); #if ZEND_RC_DEBUG zend_rc_debug = orig_rc_debug; #endif @@ -797,22 +791,22 @@ PHPAPI int php_parse_user_ini_file(const char *dirname, const char *ini_filename /* }}} */ /* {{{ php_ini_activate_config */ -PHPAPI void php_ini_activate_config(HashTable *source_hash, int modify_type, int stage) +PHPAPI void php_ini_activate_config(const HashTable *source_hash, int modify_type, int stage) { zend_string *str; zval *data; /* Walk through config hash and alter matching ini entries using the values found in the hash */ ZEND_HASH_MAP_FOREACH_STR_KEY_VAL(source_hash, str, data) { - zend_string *data_str = zend_string_dup(Z_STR_P(data), 0); - zend_alter_ini_entry_ex(str, data_str, modify_type, stage, 0); + zend_string *data_str = zend_string_dup(Z_STR_P(data), false); + zend_alter_ini_entry_ex(str, data_str, modify_type, stage, false); zend_string_release(data_str); } ZEND_HASH_FOREACH_END(); } /* }}} */ /* {{{ php_ini_has_per_dir_config */ -PHPAPI int php_ini_has_per_dir_config(void) +PHPAPI bool php_ini_has_per_dir_config(void) { return has_per_dir_config; } @@ -861,7 +855,7 @@ PHPAPI void php_ini_activate_per_dir_config(char *path, size_t path_len) /* }}} */ /* {{{ php_ini_has_per_host_config */ -PHPAPI int php_ini_has_per_host_config(void) +PHPAPI bool php_ini_has_per_host_config(void) { return has_per_host_config; } @@ -896,7 +890,7 @@ PHPAPI zval *cfg_get_entry(const char *name, size_t name_length) /* }}} */ /* {{{ cfg_get_long */ -PHPAPI int cfg_get_long(const char *varname, zend_long *result) +PHPAPI zend_result cfg_get_long(const char *varname, zend_long *result) { zval *tmp; @@ -910,7 +904,7 @@ PHPAPI int cfg_get_long(const char *varname, zend_long *result) /* }}} */ /* {{{ cfg_get_double */ -PHPAPI int cfg_get_double(const char *varname, double *result) +PHPAPI zend_result cfg_get_double(const char *varname, double *result) { zval *tmp; @@ -924,7 +918,7 @@ PHPAPI int cfg_get_double(const char *varname, double *result) /* }}} */ /* {{{ cfg_get_string */ -PHPAPI int cfg_get_string(const char *varname, char **result) +PHPAPI zend_result cfg_get_string(const char *varname, char **result) { zval *tmp; diff --git a/main/php_ini.h b/main/php_ini.h index a5538efd707..4253ce43fbe 100644 --- a/main/php_ini.h +++ b/main/php_ini.h @@ -21,18 +21,18 @@ BEGIN_EXTERN_C() PHPAPI void config_zval_dtor(zval *zvalue); -int php_init_config(void); -int php_shutdown_config(void); +void php_init_config(void); +void php_shutdown_config(void); void php_ini_register_extensions(void); PHPAPI zval *cfg_get_entry_ex(zend_string *name); PHPAPI zval *cfg_get_entry(const char *name, size_t name_length); -PHPAPI int cfg_get_long(const char *varname, zend_long *result); -PHPAPI int cfg_get_double(const char *varname, double *result); -PHPAPI int cfg_get_string(const char *varname, char **result); -PHPAPI int php_parse_user_ini_file(const char *dirname, const char *ini_filename, HashTable *target_hash); -PHPAPI void php_ini_activate_config(HashTable *source_hash, int modify_type, int stage); -PHPAPI int php_ini_has_per_dir_config(void); -PHPAPI int php_ini_has_per_host_config(void); +PHPAPI zend_result cfg_get_long(const char *varname, zend_long *result); +PHPAPI zend_result cfg_get_double(const char *varname, double *result); +PHPAPI zend_result cfg_get_string(const char *varname, char **result); +PHPAPI zend_result php_parse_user_ini_file(const char *dirname, const char *ini_filename, HashTable *target_hash); +PHPAPI void php_ini_activate_config(const HashTable *source_hash, int modify_type, int stage); +PHPAPI bool php_ini_has_per_dir_config(void); +PHPAPI bool php_ini_has_per_host_config(void); PHPAPI void php_ini_activate_per_dir_config(char *path, size_t path_len); PHPAPI void php_ini_activate_per_host_config(const char *host, size_t host_len); PHPAPI HashTable* php_ini_get_configuration_hash(void); diff --git a/main/php_main.h b/main/php_main.h index a5b049487db..bd28a0dee1d 100644 --- a/main/php_main.h +++ b/main/php_main.h @@ -49,6 +49,7 @@ ZEND_ATTRIBUTE_CONST PHPAPI const char *php_build_provider(void); PHPAPI char *php_get_version(sapi_module_struct *sapi_module); PHPAPI void php_print_version(sapi_module_struct *sapi_module); +PHPAPI void php_child_init(void); PHPAPI zend_result php_request_startup(void); PHPAPI void php_request_shutdown(void *dummy); PHPAPI zend_result php_module_startup(sapi_module_struct *sf, zend_module_entry *additional_module); diff --git a/main/php_network.h b/main/php_network.h index 94a2508c89e..1d941265bd9 100644 --- a/main/php_network.h +++ b/main/php_network.h @@ -313,9 +313,9 @@ END_EXTERN_C() struct _php_netstream_data_t { php_socket_t socket; - char is_blocked; + bool is_blocked; + bool timeout_event; struct timeval timeout; - char timeout_event; size_t ownsize; }; typedef struct _php_netstream_data_t php_netstream_data_t; diff --git a/main/php_open_temporary_file.c b/main/php_open_temporary_file.c index b45537935a5..3a410eb7fa2 100644 --- a/main/php_open_temporary_file.c +++ b/main/php_open_temporary_file.c @@ -186,6 +186,7 @@ static int php_do_open_temporary_file(const char *path, const char *pfx, zend_st free(random_prefix_w); efree(random_prefix); efree(new_state.cwd); + free(opened_path); return -1; } assert(strlen(opened_path) == opened_path_len); diff --git a/main/php_streams.h b/main/php_streams.h index 81fba301c68..1c52539cfca 100644 --- a/main/php_streams.h +++ b/main/php_streams.h @@ -361,7 +361,7 @@ PHPAPI int _php_stream_seek(php_stream *stream, zend_off_t offset, int whence); #define php_stream_rewind(stream) _php_stream_seek((stream), 0L, SEEK_SET) #define php_stream_seek(stream, offset, whence) _php_stream_seek((stream), (offset), (whence)) -PHPAPI zend_off_t _php_stream_tell(php_stream *stream); +PHPAPI zend_off_t _php_stream_tell(const php_stream *stream); #define php_stream_tell(stream) _php_stream_tell((stream)) PHPAPI ssize_t _php_stream_read(php_stream *stream, char *buf, size_t count); @@ -531,7 +531,7 @@ PHPAPI zend_result _php_stream_copy_to_stream_ex(php_stream *src, php_stream *de /* read all data from stream and put into a buffer. Caller must free buffer * when done. */ -PHPAPI zend_string *_php_stream_copy_to_mem(php_stream *src, size_t maxlen, int persistent STREAMS_DC); +PHPAPI zend_string *_php_stream_copy_to_mem(php_stream *src, size_t maxlen, bool persistent STREAMS_DC); #define php_stream_copy_to_mem(src, maxlen, persistent) _php_stream_copy_to_mem((src), (maxlen), (persistent) STREAMS_CC) /* output all data from a stream */ @@ -561,7 +561,7 @@ END_EXTERN_C() #define PHP_STREAM_CAST_INTERNAL 0x20000000 /* stream cast for internal use */ #define PHP_STREAM_CAST_MASK (PHP_STREAM_CAST_TRY_HARD | PHP_STREAM_CAST_RELEASE | PHP_STREAM_CAST_INTERNAL) BEGIN_EXTERN_C() -PHPAPI int _php_stream_cast(php_stream *stream, int castas, void **ret, int show_err); +PHPAPI zend_result _php_stream_cast(php_stream *stream, int castas, void **ret, int show_err); END_EXTERN_C() /* use this to check if a stream can be cast into another form */ #define php_stream_can_cast(stream, as) _php_stream_cast((stream), (as), NULL, 0) @@ -626,7 +626,7 @@ END_EXTERN_C() /* this flag is only used by include/require functions */ #define STREAM_OPEN_FOR_ZEND_STREAM 0x00010000 -int php_init_stream_wrappers(int module_number); +zend_result php_init_stream_wrappers(int module_number); void php_shutdown_stream_wrappers(int module_number); void php_shutdown_stream_hashes(void); PHP_RSHUTDOWN_FUNCTION(streams); @@ -646,15 +646,18 @@ PHPAPI const char *php_stream_locate_eol(php_stream *stream, zend_string *buf); /* pushes an error message onto the stack for a wrapper instance */ PHPAPI void php_stream_wrapper_log_error(const php_stream_wrapper *wrapper, int options, const char *fmt, ...) PHP_ATTRIBUTE_FORMAT(printf, 3, 4); -#define PHP_STREAM_UNCHANGED 0 /* orig stream was seekable anyway */ -#define PHP_STREAM_RELEASED 1 /* newstream should be used; origstream is no longer valid */ -#define PHP_STREAM_FAILED 2 /* an error occurred while attempting conversion */ -#define PHP_STREAM_CRITICAL 3 /* an error occurred; origstream is in an unknown state; you should close origstream */ +typedef enum { + PHP_STREAM_UNCHANGED = 0, /* orig stream was seekable anyway */ + PHP_STREAM_RELEASED = 1, /* newstream should be used; origstream is no longer valid */ + PHP_STREAM_FAILED = 2, /* an error occurred while attempting conversion */ + PHP_STREAM_CRITICAL = 3, /* an error occurred; origstream is in an unknown state; you should close origstream */ +} php_stream_make_seekable_status; + #define PHP_STREAM_NO_PREFERENCE 0 #define PHP_STREAM_PREFER_STDIO 1 #define PHP_STREAM_FORCE_CONVERSION 2 /* DO NOT call this on streams that are referenced by resources! */ -PHPAPI int _php_stream_make_seekable(php_stream *origstream, php_stream **newstream, int flags STREAMS_DC); +PHPAPI php_stream_make_seekable_status _php_stream_make_seekable(php_stream *origstream, php_stream **newstream, int flags STREAMS_DC); #define php_stream_make_seekable(origstream, newstream, flags) _php_stream_make_seekable((origstream), (newstream), (flags) STREAMS_CC) /* Give other modules access to the url_stream_wrappers_hash and stream_filters_hash */ diff --git a/main/php_variables.c b/main/php_variables.c index b81c049f6c5..91eb0a7f5ce 100644 --- a/main/php_variables.c +++ b/main/php_variables.c @@ -346,7 +346,7 @@ static bool add_post_var(zval *arr, post_var_data_t *var, bool eof) size_t new_vlen; if (var->ptr >= var->end) { - return 0; + return false; } start = var->ptr + var->already_scanned; @@ -354,7 +354,7 @@ static bool add_post_var(zval *arr, post_var_data_t *var, bool eof) if (!vsep) { if (!eof) { var->already_scanned = var->end - var->ptr; - return 0; + return false; } else { vsep = var->end; } @@ -387,10 +387,10 @@ static bool add_post_var(zval *arr, post_var_data_t *var, bool eof) var->ptr = vsep + (vsep != var->end); var->already_scanned = 0; - return 1; + return true; } -static inline int add_post_vars(zval *arr, post_var_data_t *vars, bool eof) +static inline zend_result add_post_vars(zval *arr, post_var_data_t *vars, bool eof) { uint64_t max_vars = REQUEST_PARSE_BODY_OPTION_GET(max_input_vars, PG(max_input_vars)); @@ -782,7 +782,7 @@ static void php_autoglobal_merge(HashTable *dest, HashTable *src) /* }}} */ /* {{{ php_hash_environment */ -PHPAPI int php_hash_environment(void) +PHPAPI zend_result php_hash_environment(void) { memset(PG(http_globals), 0, sizeof(PG(http_globals))); zend_activate_auto_globals(); @@ -805,7 +805,7 @@ static bool php_auto_globals_create_get(zend_string *name) zend_hash_update(&EG(symbol_table), name, &PG(http_globals)[TRACK_VARS_GET]); Z_ADDREF(PG(http_globals)[TRACK_VARS_GET]); - return 0; /* don't rearm */ + return false; /* don't rearm */ } static bool php_auto_globals_create_post(zend_string *name) @@ -824,7 +824,7 @@ static bool php_auto_globals_create_post(zend_string *name) zend_hash_update(&EG(symbol_table), name, &PG(http_globals)[TRACK_VARS_POST]); Z_ADDREF(PG(http_globals)[TRACK_VARS_POST]); - return 0; /* don't rearm */ + return false; /* don't rearm */ } static bool php_auto_globals_create_cookie(zend_string *name) @@ -839,7 +839,7 @@ static bool php_auto_globals_create_cookie(zend_string *name) zend_hash_update(&EG(symbol_table), name, &PG(http_globals)[TRACK_VARS_COOKIE]); Z_ADDREF(PG(http_globals)[TRACK_VARS_COOKIE]); - return 0; /* don't rearm */ + return false; /* don't rearm */ } static bool php_auto_globals_create_files(zend_string *name) @@ -851,7 +851,7 @@ static bool php_auto_globals_create_files(zend_string *name) zend_hash_update(&EG(symbol_table), name, &PG(http_globals)[TRACK_VARS_FILES]); Z_ADDREF(PG(http_globals)[TRACK_VARS_FILES]); - return 0; /* don't rearm */ + return false; /* don't rearm */ } /* Ugly hack to fix HTTP_PROXY issue, see bug #72573 */ @@ -905,7 +905,7 @@ static bool php_auto_globals_create_server(zend_string *name) * ignore this issue, as it would probably require larger changes. */ HT_ALLOW_COW_VIOLATION(Z_ARRVAL(PG(http_globals)[TRACK_VARS_SERVER])); - return 0; /* don't rearm */ + return false; /* don't rearm */ } static bool php_auto_globals_create_env(zend_string *name) @@ -921,7 +921,7 @@ static bool php_auto_globals_create_env(zend_string *name) zend_hash_update(&EG(symbol_table), name, &PG(http_globals)[TRACK_VARS_ENV]); Z_ADDREF(PG(http_globals)[TRACK_VARS_ENV]); - return 0; /* don't rearm */ + return false; /* don't rearm */ } static bool php_auto_globals_create_request(zend_string *name) @@ -965,7 +965,7 @@ static bool php_auto_globals_create_request(zend_string *name) } zend_hash_update(&EG(symbol_table), name, &form_variables); - return 0; + return false; } void php_startup_auto_globals(void) diff --git a/main/php_variables.h b/main/php_variables.h index f2b4b8cae24..5cb43890bd7 100644 --- a/main/php_variables.h +++ b/main/php_variables.h @@ -39,7 +39,7 @@ PHPAPI void php_register_variable_ex(const char *var, zval *val, zval *track_var PHPAPI void php_register_known_variable(const char *var, size_t var_len, zval *value, zval *track_vars_array); PHPAPI void php_build_argv(const char *s, zval *track_vars_array); -PHPAPI int php_hash_environment(void); +PHPAPI zend_result php_hash_environment(void); END_EXTERN_C() #define NUM_TRACK_VARS 6 diff --git a/main/streams/cast.c b/main/streams/cast.c index 6e5c63fb3b2..4b718302457 100644 --- a/main/streams/cast.c +++ b/main/streams/cast.c @@ -191,7 +191,7 @@ void php_stream_mode_sanitize_fdopen_fopencookie(php_stream *stream, char *resul /* }}} */ /* {{{ php_stream_cast */ -PHPAPI int _php_stream_cast(php_stream *stream, int castas, void **ret, int show_err) +PHPAPI zend_result _php_stream_cast(php_stream *stream, int castas, void **ret, int show_err) { int flags = castas & PHP_STREAM_CAST_MASK; castas &= ~PHP_STREAM_CAST_MASK; @@ -273,12 +273,12 @@ PHPAPI int _php_stream_cast(php_stream *stream, int castas, void **ret, int show newstream = php_stream_fopen_tmpfile(); if (newstream) { - int retcopy = php_stream_copy_to_stream_ex(stream, newstream, PHP_STREAM_COPY_ALL, NULL); + zend_result retcopy = php_stream_copy_to_stream_ex(stream, newstream, PHP_STREAM_COPY_ALL, NULL); if (retcopy != SUCCESS) { php_stream_close(newstream); } else { - int retcast = php_stream_cast(newstream, castas | flags, (void **)ret, show_err); + zend_result retcast = php_stream_cast(newstream, castas | flags, (void **)ret, show_err); if (retcast == SUCCESS) { rewind(*(FILE**)ret); @@ -370,7 +370,7 @@ PHPAPI FILE * _php_stream_open_wrapper_as_file(char *path, char *mode, int optio /* }}} */ /* {{{ php_stream_make_seekable */ -PHPAPI int _php_stream_make_seekable(php_stream *origstream, php_stream **newstream, int flags STREAMS_DC) +PHPAPI php_stream_make_seekable_status _php_stream_make_seekable(php_stream *origstream, php_stream **newstream, int flags STREAMS_DC) { if (newstream == NULL) { return PHP_STREAM_FAILED; diff --git a/main/streams/filter.c b/main/streams/filter.c index abfc5c26ae1..beaba503cbe 100644 --- a/main/streams/filter.c +++ b/main/streams/filter.c @@ -15,10 +15,8 @@ */ #include "php.h" -#include "php_globals.h" #include "php_network.h" -#include "php_open_temporary_file.h" -#include "ext/standard/file.h" +#include "ext/standard/file.h" /* For FG(stream_filters) */ #include #include @@ -40,22 +38,22 @@ PHPAPI HashTable *_php_get_stream_filters_hash(void) } /* API for registering GLOBAL filters */ -PHPAPI int php_stream_filter_register_factory(const char *filterpattern, const php_stream_filter_factory *factory) +PHPAPI zend_result php_stream_filter_register_factory(const char *filterpattern, const php_stream_filter_factory *factory) { - int ret; - zend_string *str = zend_string_init_interned(filterpattern, strlen(filterpattern), 1); + zend_result ret; + zend_string *str = zend_string_init_interned(filterpattern, strlen(filterpattern), true); ret = zend_hash_add_ptr(&stream_filters_hash, str, (void*)factory) ? SUCCESS : FAILURE; - zend_string_release_ex(str, 1); + zend_string_release_ex(str, true); return ret; } -PHPAPI int php_stream_filter_unregister_factory(const char *filterpattern) +PHPAPI zend_result php_stream_filter_unregister_factory(const char *filterpattern) { return zend_hash_str_del(&stream_filters_hash, filterpattern, strlen(filterpattern)); } /* API for registering VOLATILE wrappers */ -PHPAPI int php_stream_filter_register_factory_volatile(zend_string *filterpattern, const php_stream_filter_factory *factory) +PHPAPI zend_result php_stream_filter_register_factory_volatile(zend_string *filterpattern, const php_stream_filter_factory *factory) { if (!FG(stream_filters)) { ALLOC_HASHTABLE(FG(stream_filters)); @@ -68,9 +66,9 @@ PHPAPI int php_stream_filter_register_factory_volatile(zend_string *filterpatter /* Buckets */ -PHPAPI php_stream_bucket *php_stream_bucket_new(php_stream *stream, char *buf, size_t buflen, uint8_t own_buf, uint8_t buf_persistent) +PHPAPI php_stream_bucket *php_stream_bucket_new(const php_stream *stream, char *buf, size_t buflen, uint8_t own_buf, uint8_t buf_persistent) { - int is_persistent = php_stream_is_persistent(stream); + bool is_persistent = php_stream_is_persistent(stream); php_stream_bucket *bucket; bucket = (php_stream_bucket*)pemalloc(sizeof(php_stream_bucket), is_persistent); @@ -78,10 +76,10 @@ PHPAPI php_stream_bucket *php_stream_bucket_new(php_stream *stream, char *buf, s if (is_persistent && !buf_persistent) { /* all data in a persistent bucket must also be persistent */ - bucket->buf = pemalloc(buflen, 1); + bucket->buf = pemalloc(buflen, true); memcpy(bucket->buf, buf, buflen); bucket->buflen = buflen; - bucket->own_buf = 1; + bucket->own_buf = true; } else { bucket->buf = buf; bucket->buflen = buflen; @@ -118,7 +116,7 @@ PHPAPI php_stream_bucket *php_stream_bucket_make_writeable(php_stream_bucket *bu memcpy(retval->buf, bucket->buf, retval->buflen); retval->refcount = 1; - retval->own_buf = 1; + retval->own_buf = true; php_stream_bucket_delref(bucket); @@ -134,14 +132,14 @@ PHPAPI int php_stream_bucket_split(php_stream_bucket *in, php_stream_bucket **le (*left)->buflen = length; memcpy((*left)->buf, in->buf, length); (*left)->refcount = 1; - (*left)->own_buf = 1; + (*left)->own_buf = true; (*left)->is_persistent = in->is_persistent; (*right)->buflen = in->buflen - length; (*right)->buf = pemalloc((*right)->buflen, in->is_persistent); memcpy((*right)->buf, in->buf + length, (*right)->buflen); (*right)->refcount = 1; - (*right)->own_buf = 1; + (*right)->own_buf = true; (*right)->is_persistent = in->is_persistent; return SUCCESS; @@ -282,7 +280,7 @@ PHPAPI void php_stream_filter_free(php_stream_filter *filter) pefree(filter, filter->is_persistent); } -PHPAPI int php_stream_filter_prepend_ex(php_stream_filter_chain *chain, php_stream_filter *filter) +PHPAPI void php_stream_filter_prepend_ex(php_stream_filter_chain *chain, php_stream_filter *filter) { filter->next = chain->head; filter->prev = NULL; @@ -294,8 +292,6 @@ PHPAPI int php_stream_filter_prepend_ex(php_stream_filter_chain *chain, php_stre } chain->head = filter; filter->chain = chain; - - return SUCCESS; } PHPAPI void _php_stream_filter_prepend(php_stream_filter_chain *chain, php_stream_filter *filter) @@ -303,7 +299,7 @@ PHPAPI void _php_stream_filter_prepend(php_stream_filter_chain *chain, php_strea php_stream_filter_prepend_ex(chain, filter); } -PHPAPI int php_stream_filter_append_ex(php_stream_filter_chain *chain, php_stream_filter *filter) +PHPAPI zend_result php_stream_filter_append_ex(php_stream_filter_chain *chain, php_stream_filter *filter) { php_stream *stream = chain->stream; @@ -395,7 +391,7 @@ PHPAPI void _php_stream_filter_append(php_stream_filter_chain *chain, php_stream } } -PHPAPI int _php_stream_filter_flush(php_stream_filter *filter, int finish) +PHPAPI zend_result _php_stream_filter_flush(php_stream_filter *filter, bool finish) { php_stream_bucket_brigade brig_a = { NULL, NULL }, brig_b = { NULL, NULL }, *inp = &brig_a, *outp = &brig_b, *brig_temp; php_stream_bucket *bucket; @@ -403,7 +399,7 @@ PHPAPI int _php_stream_filter_flush(php_stream_filter *filter, int finish) php_stream_filter *current; php_stream *stream; size_t flushed_size = 0; - long flags = (finish ? PSFS_FLAG_FLUSH_CLOSE : PSFS_FLAG_FLUSH_INC); + int flags = (finish ? PSFS_FLAG_FLUSH_CLOSE : PSFS_FLAG_FLUSH_INC); if (!filter->chain || !filter->chain->stream) { /* Filter is not attached to a chain, or chain is somehow not part of a stream */ @@ -480,7 +476,7 @@ PHPAPI int _php_stream_filter_flush(php_stream_filter *filter, int finish) return SUCCESS; } -PHPAPI php_stream_filter *php_stream_filter_remove(php_stream_filter *filter, int call_dtor) +PHPAPI php_stream_filter *php_stream_filter_remove(php_stream_filter *filter, bool call_dtor) { if (filter->prev) { filter->prev->next = filter->next; diff --git a/main/streams/php_stream_context.h b/main/streams/php_stream_context.h index f61604c929d..56574704704 100644 --- a/main/streams/php_stream_context.h +++ b/main/streams/php_stream_context.h @@ -44,7 +44,7 @@ typedef struct _php_stream_notifier php_stream_notifier; struct _php_stream_notifier { php_stream_notification_func func; void (*dtor)(php_stream_notifier *notifier); - zend_fcall_info_cache *fcc; + void *ptr; int mask; size_t progress, progress_max; /* position for progress notification */ }; @@ -59,7 +59,7 @@ BEGIN_EXTERN_C() PHPAPI int php_le_stream_context(void); PHPAPI void php_stream_context_free(php_stream_context *context); PHPAPI php_stream_context *php_stream_context_alloc(void); -PHPAPI zval *php_stream_context_get_option(php_stream_context *context, +PHPAPI zval *php_stream_context_get_option(const php_stream_context *context, const char *wrappername, const char *optionname); PHPAPI void php_stream_context_set_option(php_stream_context *context, const char *wrappername, const char *optionname, zval *optionvalue); diff --git a/main/streams/php_stream_filter_api.h b/main/streams/php_stream_filter_api.h index ee6ab75f38c..e224b85b2d9 100644 --- a/main/streams/php_stream_filter_api.h +++ b/main/streams/php_stream_filter_api.h @@ -44,8 +44,8 @@ struct _php_stream_bucket { char *buf; size_t buflen; /* if non-zero, buf should be pefreed when the bucket is destroyed */ - uint8_t own_buf; - uint8_t is_persistent; + bool own_buf; + bool is_persistent; /* destroy this struct when refcount falls to zero */ int refcount; @@ -63,7 +63,7 @@ typedef enum { /* Buckets API. */ BEGIN_EXTERN_C() -PHPAPI php_stream_bucket *php_stream_bucket_new(php_stream *stream, char *buf, size_t buflen, uint8_t own_buf, uint8_t buf_persistent); +PHPAPI php_stream_bucket *php_stream_bucket_new(const php_stream *stream, char *buf, size_t buflen, uint8_t own_buf, uint8_t buf_persistent); PHPAPI int php_stream_bucket_split(php_stream_bucket *in, php_stream_bucket **left, php_stream_bucket **right, size_t length); PHPAPI void php_stream_bucket_delref(php_stream_bucket *bucket); #define php_stream_bucket_addref(bucket) (bucket)->refcount++ @@ -121,11 +121,11 @@ struct _php_stream_filter { /* stack filter onto a stream */ BEGIN_EXTERN_C() PHPAPI void _php_stream_filter_prepend(php_stream_filter_chain *chain, php_stream_filter *filter); -PHPAPI int php_stream_filter_prepend_ex(php_stream_filter_chain *chain, php_stream_filter *filter); +PHPAPI void php_stream_filter_prepend_ex(php_stream_filter_chain *chain, php_stream_filter *filter); PHPAPI void _php_stream_filter_append(php_stream_filter_chain *chain, php_stream_filter *filter); -PHPAPI int php_stream_filter_append_ex(php_stream_filter_chain *chain, php_stream_filter *filter); -PHPAPI int _php_stream_filter_flush(php_stream_filter *filter, int finish); -PHPAPI php_stream_filter *php_stream_filter_remove(php_stream_filter *filter, int call_dtor); +PHPAPI zend_result php_stream_filter_append_ex(php_stream_filter_chain *chain, php_stream_filter *filter); +PHPAPI zend_result _php_stream_filter_flush(php_stream_filter *filter, bool finish); +PHPAPI php_stream_filter *php_stream_filter_remove(php_stream_filter *filter, bool call_dtor); PHPAPI void php_stream_filter_free(php_stream_filter *filter); PHPAPI php_stream_filter *_php_stream_filter_alloc(const php_stream_filter_ops *fops, void *abstract, uint8_t persistent STREAMS_DC); END_EXTERN_C() @@ -142,8 +142,8 @@ typedef struct _php_stream_filter_factory { } php_stream_filter_factory; BEGIN_EXTERN_C() -PHPAPI int php_stream_filter_register_factory(const char *filterpattern, const php_stream_filter_factory *factory); -PHPAPI int php_stream_filter_unregister_factory(const char *filterpattern); -PHPAPI int php_stream_filter_register_factory_volatile(zend_string *filterpattern, const php_stream_filter_factory *factory); +PHPAPI zend_result php_stream_filter_register_factory(const char *filterpattern, const php_stream_filter_factory *factory); +PHPAPI zend_result php_stream_filter_unregister_factory(const char *filterpattern); +PHPAPI zend_result php_stream_filter_register_factory_volatile(zend_string *filterpattern, const php_stream_filter_factory *factory); PHPAPI php_stream_filter *php_stream_filter_create(const char *filtername, zval *filterparams, uint8_t persistent); END_EXTERN_C() diff --git a/main/streams/streams.c b/main/streams/streams.c index 2eef790863f..42e08e91077 100644 --- a/main/streams/streams.c +++ b/main/streams/streams.c @@ -35,9 +35,9 @@ /* {{{ resource and registration code */ /* Global wrapper hash, copied to FG(stream_wrappers) on registration of volatile wrapper */ static HashTable url_stream_wrappers_hash; -static int le_stream = FAILURE; /* true global */ -static int le_pstream = FAILURE; /* true global */ -static int le_stream_filter = FAILURE; /* true global */ +static int le_stream = -1; /* true global */ +static int le_pstream = -1; /* true global */ +static int le_stream_filter = -1; /* true global */ PHPAPI int php_file_le_stream(void) { @@ -880,7 +880,7 @@ PHPAPI int _php_stream_stat(php_stream *stream, php_stream_statbuf *ssb) PHPAPI const char *php_stream_locate_eol(php_stream *stream, zend_string *buf) { size_t avail; - const char *cr, *lf, *eol = NULL; + const char *eol = NULL; const char *readptr; if (!buf) { @@ -893,8 +893,8 @@ PHPAPI const char *php_stream_locate_eol(php_stream *stream, zend_string *buf) /* Look for EOL */ if (stream->flags & PHP_STREAM_FLAG_DETECT_EOL) { - cr = memchr(readptr, '\r', avail); - lf = memchr(readptr, '\n', avail); + const char *cr = memchr(readptr, '\r', avail); + const char *lf = memchr(readptr, '\n', avail); if (cr && lf != cr + 1 && !(lf && lf < cr)) { /* mac */ @@ -1041,12 +1041,13 @@ PHPAPI char *_php_stream_get_line(php_stream *stream, char *buf, size_t maxlen, #define STREAM_BUFFERED_AMOUNT(stream) \ ((size_t)(((stream)->writepos) - (stream)->readpos)) -static const char *_php_stream_search_delim(php_stream *stream, - size_t maxlen, - size_t skiplen, - const char *delim, /* non-empty! */ - size_t delim_len) -{ +static const char *_php_stream_search_delim( + const php_stream *stream, + size_t maxlen, + size_t skiplen, + const char *delim, /* non-empty! */ + size_t delim_len +) { size_t seek_len; /* set the maximum number of bytes we're allowed to read from buffer */ @@ -1217,16 +1218,15 @@ static ssize_t _php_stream_write_filtered(php_stream *stream, const char *buf, s size_t consumed = 0; php_stream_bucket *bucket; php_stream_bucket_brigade brig_in = { NULL, NULL }, brig_out = { NULL, NULL }; - php_stream_bucket_brigade *brig_inp = &brig_in, *brig_outp = &brig_out, *brig_swap; + php_stream_bucket_brigade *brig_inp = &brig_in, *brig_outp = &brig_out; php_stream_filter_status_t status = PSFS_ERR_FATAL; - php_stream_filter *filter; if (buf) { bucket = php_stream_bucket_new(stream, (char *)buf, count, 0, 0); php_stream_bucket_append(&brig_in, bucket); } - for (filter = stream->writefilters.head; filter; filter = filter->next) { + for (php_stream_filter *filter = stream->writefilters.head; filter; filter = filter->next) { /* for our return value, we are interested in the number of bytes consumed from * the first filter in the chain */ status = filter->fops->filter(stream, filter, brig_inp, brig_outp, @@ -1238,7 +1238,7 @@ static ssize_t _php_stream_write_filtered(php_stream *stream, const char *buf, s /* brig_out becomes brig_in. * brig_in will always be empty here, as the filter MUST attach any un-consumed buckets * to its own brigade */ - brig_swap = brig_inp; + php_stream_bucket_brigade *brig_swap = brig_inp; brig_inp = brig_outp; brig_outp = brig_swap; memset(brig_outp, 0, sizeof(*brig_outp)); @@ -1340,7 +1340,7 @@ PHPAPI ssize_t _php_stream_printf(php_stream *stream, const char *fmt, ...) return count; } -PHPAPI zend_off_t _php_stream_tell(php_stream *stream) +PHPAPI zend_off_t _php_stream_tell(const php_stream *stream) { return stream->position; } @@ -1529,13 +1529,11 @@ PHPAPI ssize_t _php_stream_passthru(php_stream * stream STREAMS_DC) } -PHPAPI zend_string *_php_stream_copy_to_mem(php_stream *src, size_t maxlen, int persistent STREAMS_DC) +PHPAPI zend_string *_php_stream_copy_to_mem(php_stream *src, size_t maxlen, bool persistent STREAMS_DC) { ssize_t ret = 0; char *ptr; size_t len = 0, buflen; - int step = CHUNK_SIZE; - int min_room = CHUNK_SIZE / 4; php_stream_statbuf ssbuf; zend_string *result; @@ -1578,20 +1576,21 @@ PHPAPI zend_string *_php_stream_copy_to_mem(php_stream *src, size_t maxlen, int * we can. Note that the stream may be filtered, in which case the stat * result may be inaccurate, as the filter may inflate or deflate the * number of bytes that we can read. In order to avoid an upsize followed - * by a downsize of the buffer, overestimate by the step size (which is + * by a downsize of the buffer, overestimate by the CHUNK_SIZE size (which is * 8K). */ if (php_stream_stat(src, &ssbuf) == 0 && ssbuf.sb.st_size > 0) { - buflen = MAX(ssbuf.sb.st_size - src->position, 0) + step; + buflen = MAX(ssbuf.sb.st_size - src->position, 0) + CHUNK_SIZE; if (maxlen > 0 && buflen > maxlen) { buflen = maxlen; } } else { - buflen = step; + buflen = CHUNK_SIZE; } result = zend_string_alloc(buflen, persistent); ptr = ZSTR_VAL(result); + const int min_room = CHUNK_SIZE / 4; // TODO: Propagate error? while ((ret = php_stream_read(src, ptr, buflen - len)) > 0) { len += ret; @@ -1599,10 +1598,10 @@ PHPAPI zend_string *_php_stream_copy_to_mem(php_stream *src, size_t maxlen, int if (maxlen == len) { break; } - if (maxlen > 0 && buflen + step > maxlen) { + if (maxlen > 0 && buflen + CHUNK_SIZE > maxlen) { buflen = maxlen; } else { - buflen += step; + buflen += CHUNK_SIZE; } result = zend_string_extend(result, buflen, persistent); ptr = ZSTR_VAL(result) + len; @@ -1869,7 +1868,7 @@ void php_shutdown_stream_hashes(void) } } -int php_init_stream_wrappers(int module_number) +zend_result php_init_stream_wrappers(int module_number) { le_stream = zend_register_list_destructors_ex(stream_resource_regular_dtor, NULL, "stream", module_number); le_pstream = zend_register_list_destructors_ex(NULL, stream_resource_persistent_dtor, "persistent stream", module_number); @@ -1903,11 +1902,9 @@ void php_shutdown_stream_wrappers(int module_number) /* Validate protocol scheme names during registration * Must conform to /^[a-zA-Z0-9+.-]+$/ */ -static inline zend_result php_stream_wrapper_scheme_validate(const char *protocol, unsigned int protocol_len) +static inline zend_result php_stream_wrapper_scheme_validate(const char *protocol, size_t protocol_len) { - unsigned int i; - - for(i = 0; i < protocol_len; i++) { + for (size_t i = 0; i < protocol_len; i++) { if (!isalnum((int)protocol[i]) && protocol[i] != '+' && protocol[i] != '-' && @@ -1975,7 +1972,7 @@ PHPAPI zend_result php_unregister_url_stream_wrapper_volatile(zend_string *proto /* {{{ php_stream_locate_url_wrapper */ PHPAPI php_stream_wrapper *php_stream_locate_url_wrapper(const char *path, const char **path_for_open, int options) { - HashTable *wrapper_hash = (FG(stream_wrappers) ? FG(stream_wrappers) : &url_stream_wrappers_hash); + const HashTable *wrapper_hash = (FG(stream_wrappers) ? FG(stream_wrappers) : &url_stream_wrappers_hash); php_stream_wrapper *wrapper = NULL; const char *p, *protocol = NULL; size_t n = 0; @@ -2023,16 +2020,16 @@ PHPAPI php_stream_wrapper *php_stream_locate_url_wrapper(const char *path, const php_stream_wrapper *plain_files_wrapper = (php_stream_wrapper*)&php_plain_files_wrapper; if (protocol) { - int localhost = 0; + bool localhost = false; if (!strncasecmp(path, "file://localhost/", 17)) { - localhost = 1; + localhost = true; } #ifdef PHP_WIN32 - if (localhost == 0 && path[n+3] != '\0' && path[n+3] != '/' && path[n+4] != ':') { + if (!localhost && path[n+3] != '\0' && path[n+3] != '/' && path[n+4] != ':') { #else - if (localhost == 0 && path[n+3] != '\0' && path[n+3] != '/') { + if (!localhost && path[n+3] != '\0' && path[n+3] != '/') { #endif if (options & REPORT_ERRORS) { php_error_docref(NULL, E_WARNING, "Remote host file access not supported, %s", path); @@ -2043,7 +2040,7 @@ PHPAPI php_stream_wrapper *php_stream_locate_url_wrapper(const char *path, const if (path_for_open) { /* skip past protocol and :/, but handle windows correctly */ *path_for_open = (char*)path + n + 1; - if (localhost == 1) { + if (localhost) { (*path_for_open) += 11; } while (*(++*path_for_open)=='/') { @@ -2262,7 +2259,7 @@ PHPAPI php_stream *_php_stream_open_wrapper_ex(const char *path, const char *mod /* if the caller asked for a persistent stream but the wrapper did not * return one, force an error here */ - if (stream && (options & STREAM_OPEN_PERSISTENT) && !stream->is_persistent) { + if (stream && persistent && !stream->is_persistent) { php_stream_wrapper_log_error(wrapper, options & ~REPORT_ERRORS, "wrapper does not support persistent streams"); php_stream_close(stream); @@ -2416,7 +2413,7 @@ PHPAPI void php_stream_notification_free(php_stream_notifier *notifier) efree(notifier); } -PHPAPI zval *php_stream_context_get_option(php_stream_context *context, +PHPAPI zval *php_stream_context_get_option(const php_stream_context *context, const char *wrappername, const char *optionname) { zval *wrapperhash; diff --git a/main/streams/transports.c b/main/streams/transports.c index 38850a3b541..83297d9a06c 100644 --- a/main/streams/transports.c +++ b/main/streams/transports.c @@ -130,7 +130,7 @@ PHPAPI php_stream *_php_stream_xport_create(const char *name, size_t namelen, in } stream = (factory)(protocol, n, - (char*)name, namelen, persistent_id, options, flags, timeout, + name, namelen, persistent_id, options, flags, timeout, context STREAMS_REL_CC); if (stream) { diff --git a/main/streams/userspace.c b/main/streams/userspace.c index 0bb80acf6b7..64aa58f776b 100644 --- a/main/streams/userspace.c +++ b/main/streams/userspace.c @@ -251,13 +251,6 @@ typedef struct _php_userstream_data php_userstream_data_t; }}} **/ -static zend_result call_method_if_exists( - zval *object, zval *method_name, zval *retval, uint32_t param_count, zval *params) -{ - return zend_call_method_if_exists( - Z_OBJ_P(object), Z_STR_P(method_name), retval, param_count, params); -} - static void user_stream_create_object(struct php_user_stream_wrapper *uwrap, php_stream_context *context, zval *object) { if (uwrap->ce->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_TRAIT|ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) { @@ -295,9 +288,8 @@ static php_stream *user_wrapper_opener(php_stream_wrapper *wrapper, const char * { struct php_user_stream_wrapper *uwrap = (struct php_user_stream_wrapper*)wrapper->abstract; php_userstream_data_t *us; - zval zretval, zfuncname; + zval zretval; zval args[4]; - int call_result; php_stream *stream = NULL; bool old_in_user_include; @@ -321,33 +313,40 @@ static php_stream *user_wrapper_opener(php_stream_wrapper *wrapper, const char * us = emalloc(sizeof(*us)); us->wrapper = uwrap; - /* call_method_if_exists() may unregister the stream wrapper. Hold on to it. */ + /* zend_call_method_if_exists() may unregister the stream wrapper. Hold on to it. */ GC_ADDREF(us->wrapper->resource); user_stream_create_object(uwrap, context, &us->object); - if (Z_TYPE(us->object) == IS_UNDEF) { - FG(user_stream_current_filename) = NULL; - PG(in_user_include) = old_in_user_include; - efree(us); - return NULL; + if (Z_ISUNDEF(us->object)) { + goto end; } - /* call it's stream_open method - set up params first */ + /* call its stream_open method - set up params first */ ZVAL_STRING(&args[0], filename); ZVAL_STRING(&args[1], mode); ZVAL_LONG(&args[2], options); ZVAL_NEW_REF(&args[3], &EG(uninitialized_zval)); - ZVAL_STRING(&zfuncname, USERSTREAM_OPEN); + zend_string *func_name = ZSTR_INIT_LITERAL(USERSTREAM_OPEN, false); + zend_result call_result = zend_call_method_if_exists(Z_OBJ(us->object), func_name, &zretval, 4, args); + zend_string_release_ex(func_name, false); - zend_try { - call_result = call_method_if_exists(&us->object, &zfuncname, &zretval, 4, args); - } zend_catch { - FG(user_stream_current_filename) = NULL; - zend_bailout(); - } zend_end_try(); + /* Keep arg3 alive if it has assigned the reference */ + zval_ptr_dtor(&args[1]); + zval_ptr_dtor(&args[0]); - if (call_result == SUCCESS && Z_TYPE(zretval) != IS_UNDEF && zval_is_true(&zretval)) { + if (UNEXPECTED(call_result == FAILURE)) { + php_stream_wrapper_log_error(wrapper, options, "\"%s::" USERSTREAM_OPEN "\" is not implemented", + ZSTR_VAL(us->wrapper->ce->name)); + zval_ptr_dtor(&args[3]); + goto end; + } + /* Exception occurred */ + if (UNEXPECTED(Z_ISUNDEF(zretval))) { + zval_ptr_dtor(&args[3]); + goto end; + } + if (zval_is_true(&zretval)) { /* the stream is now open! */ stream = php_stream_alloc_rel(&php_stream_userspace_ops, us, 0, mode); @@ -355,6 +354,7 @@ static php_stream *user_wrapper_opener(php_stream_wrapper *wrapper, const char * if (Z_ISREF(args[3]) && Z_TYPE_P(Z_REFVAL(args[3])) == IS_STRING && opened_path) { *opened_path = zend_string_copy(Z_STR_P(Z_REFVAL(args[3]))); } + // TODO Warn when assigning a non string value to the reference? /* set wrapper data to be a reference to our object */ ZVAL_COPY(&stream->wrapperdata, &us->object); @@ -363,23 +363,17 @@ static php_stream *user_wrapper_opener(php_stream_wrapper *wrapper, const char * ZSTR_VAL(us->wrapper->ce->name)); } - /* destroy everything else */ + zval_ptr_dtor(&zretval); + zval_ptr_dtor(&args[3]); + +end: + FG(user_stream_current_filename) = NULL; + PG(in_user_include) = old_in_user_include; if (stream == NULL) { zval_ptr_dtor(&us->object); - ZVAL_UNDEF(&us->object); zend_list_delete(us->wrapper->resource); efree(us); } - zval_ptr_dtor(&zretval); - zval_ptr_dtor(&zfuncname); - zval_ptr_dtor(&args[3]); - zval_ptr_dtor(&args[2]); - zval_ptr_dtor(&args[1]); - zval_ptr_dtor(&args[0]); - - FG(user_stream_current_filename) = NULL; - - PG(in_user_include) = old_in_user_include; return stream; } @@ -396,9 +390,8 @@ static php_stream *user_wrapper_opendir(php_stream_wrapper *wrapper, const char { struct php_user_stream_wrapper *uwrap = (struct php_user_stream_wrapper*)wrapper->abstract; php_userstream_data_t *us; - zval zretval, zfuncname; + zval zretval; zval args[2]; - int call_result; php_stream *stream = NULL; /* Try to catch bad usage without preventing flexibility */ @@ -410,25 +403,34 @@ static php_stream *user_wrapper_opendir(php_stream_wrapper *wrapper, const char us = emalloc(sizeof(*us)); us->wrapper = uwrap; - /* call_method_if_exists() may unregister the stream wrapper. Hold on to it. */ + /* zend_call_method_if_exists() may unregister the stream wrapper. Hold on to it. */ GC_ADDREF(us->wrapper->resource); user_stream_create_object(uwrap, context, &us->object); if (Z_TYPE(us->object) == IS_UNDEF) { - FG(user_stream_current_filename) = NULL; - efree(us); - return NULL; + goto end; } - /* call it's dir_open method - set up params first */ + /* call its dir_open method - set up params first */ ZVAL_STRING(&args[0], filename); ZVAL_LONG(&args[1], options); - ZVAL_STRING(&zfuncname, USERSTREAM_DIR_OPEN); + zend_string *func_name = ZSTR_INIT_LITERAL(USERSTREAM_DIR_OPEN, false); + zend_result call_result = zend_call_method_if_exists(Z_OBJ(us->object), func_name, &zretval, 2, args); + zend_string_release_ex(func_name, false); + zval_ptr_dtor(&args[0]); - call_result = call_method_if_exists(&us->object, &zfuncname, &zretval, 2, args); + if (UNEXPECTED(call_result == FAILURE)) { + php_stream_wrapper_log_error(wrapper, options, "\"%s::" USERSTREAM_DIR_OPEN "\" is not implemented", + ZSTR_VAL(us->wrapper->ce->name)); + goto end; + } + /* Exception occurred in call */ + if (UNEXPECTED(Z_ISUNDEF(zretval))) { + goto end; + } - if (call_result == SUCCESS && Z_TYPE(zretval) != IS_UNDEF && zval_is_true(&zretval)) { + if (zval_is_true(&zretval)) { /* the stream is now open! */ stream = php_stream_alloc_rel(&php_stream_userspace_dir_ops, us, 0, mode); @@ -438,22 +440,15 @@ static php_stream *user_wrapper_opendir(php_stream_wrapper *wrapper, const char php_stream_wrapper_log_error(wrapper, options, "\"%s::" USERSTREAM_DIR_OPEN "\" call failed", ZSTR_VAL(us->wrapper->ce->name)); } + zval_ptr_dtor(&zretval); - /* destroy everything else */ +end: + FG(user_stream_current_filename) = NULL; if (stream == NULL) { zval_ptr_dtor(&us->object); - ZVAL_UNDEF(&us->object); zend_list_delete(us->wrapper->resource); efree(us); } - zval_ptr_dtor(&zretval); - - zval_ptr_dtor(&zfuncname); - zval_ptr_dtor(&args[1]); - zval_ptr_dtor(&args[0]); - - FG(user_stream_current_filename) = NULL; - return stream; } @@ -562,38 +557,34 @@ PHP_FUNCTION(stream_wrapper_restore) static ssize_t php_userstreamop_write(php_stream *stream, const char *buf, size_t count) { - zval func_name; zval retval; - int call_result; php_userstream_data_t *us = (php_userstream_data_t *)stream->abstract; zval args[1]; ssize_t didwrite; assert(us != NULL); - ZVAL_STRINGL(&func_name, USERSTREAM_WRITE, sizeof(USERSTREAM_WRITE)-1); - ZVAL_STRINGL(&args[0], (char*)buf, count); - call_result = call_method_if_exists(&us->object, &func_name, &retval, 1, args); + zend_string *func_name = ZSTR_INIT_LITERAL(USERSTREAM_WRITE, false); + zend_result call_result = zend_call_method_if_exists(Z_OBJ(us->object), func_name, &retval, 1, args); + zend_string_release_ex(func_name, false); zval_ptr_dtor(&args[0]); - zval_ptr_dtor(&func_name); - if (EG(exception)) { + if (UNEXPECTED(call_result == FAILURE)) { + php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_WRITE " is not implemented!", + ZSTR_VAL(us->wrapper->ce->name)); + } + /* Exception occurred */ + if (Z_ISUNDEF(retval)) { return -1; } - if (call_result == SUCCESS && Z_TYPE(retval) != IS_UNDEF) { - if (Z_TYPE(retval) == IS_FALSE) { - didwrite = -1; - } else { - convert_to_long(&retval); - didwrite = Z_LVAL(retval); - } - } else { - php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_WRITE " is not implemented!", - ZSTR_VAL(us->wrapper->ce->name)); + if (Z_TYPE(retval) == IS_FALSE) { didwrite = -1; + } else { + convert_to_long(&retval); + didwrite = Z_LVAL(retval); } /* don't allow strange buffer overruns due to bogus return */ @@ -611,29 +602,23 @@ static ssize_t php_userstreamop_write(php_stream *stream, const char *buf, size_ static ssize_t php_userstreamop_read(php_stream *stream, char *buf, size_t count) { - zval func_name; zval retval; zval args[1]; - int call_result; size_t didread = 0; php_userstream_data_t *us = (php_userstream_data_t *)stream->abstract; assert(us != NULL); - ZVAL_STRINGL(&func_name, USERSTREAM_READ, sizeof(USERSTREAM_READ)-1); - ZVAL_LONG(&args[0], count); + zend_string *func_name = ZSTR_INIT_LITERAL(USERSTREAM_READ, false); + zend_result call_result = zend_call_method_if_exists(Z_OBJ(us->object), func_name, &retval, 1, args); + zend_string_release_ex(func_name, false); - call_result = call_method_if_exists(&us->object, &func_name, &retval, 1, args); - - zval_ptr_dtor(&args[0]); - zval_ptr_dtor(&func_name); - - if (EG(exception)) { + if (UNEXPECTED(Z_ISUNDEF(retval))) { return -1; } - if (call_result == FAILURE) { + if (UNEXPECTED(call_result == FAILURE)) { php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_READ " is not implemented!", ZSTR_VAL(us->wrapper->ce->name)); return -1; @@ -663,25 +648,25 @@ static ssize_t php_userstreamop_read(php_stream *stream, char *buf, size_t count /* since the user stream has no way of setting the eof flag directly, we need to ask it if we hit eof */ - ZVAL_STRINGL(&func_name, USERSTREAM_EOF, sizeof(USERSTREAM_EOF)-1); - call_result = call_method_if_exists(&us->object, &func_name, &retval, 0, NULL); - zval_ptr_dtor(&func_name); + func_name = ZSTR_INIT_LITERAL(USERSTREAM_EOF, false); + call_result = zend_call_method_if_exists(Z_OBJ(us->object), func_name, &retval, 0, NULL); + zend_string_release_ex(func_name, false); - if (EG(exception)) { + if (UNEXPECTED(call_result == FAILURE)) { + php_error_docref(NULL, E_WARNING, + "%s::" USERSTREAM_EOF " is not implemented! Assuming EOF", + ZSTR_VAL(us->wrapper->ce->name)); + stream->eof = 1; + return -1; + } + if (UNEXPECTED(Z_ISUNDEF(retval))) { stream->eof = 1; return -1; } - if (call_result == SUCCESS && Z_TYPE(retval) != IS_UNDEF && zval_is_true(&retval)) { - stream->eof = 1; - } else if (call_result == FAILURE) { - php_error_docref(NULL, E_WARNING, - "%s::" USERSTREAM_EOF " is not implemented! Assuming EOF", - ZSTR_VAL(us->wrapper->ce->name)); - + if (zval_is_true(&retval)) { stream->eof = 1; } - zval_ptr_dtor(&retval); return didread; @@ -689,18 +674,16 @@ static ssize_t php_userstreamop_read(php_stream *stream, char *buf, size_t count static int php_userstreamop_close(php_stream *stream, int close_handle) { - zval func_name; zval retval; php_userstream_data_t *us = (php_userstream_data_t *)stream->abstract; assert(us != NULL); - ZVAL_STRINGL(&func_name, USERSTREAM_CLOSE, sizeof(USERSTREAM_CLOSE)-1); - - call_method_if_exists(&us->object, &func_name, &retval, 0, NULL); + zend_string *func_name = ZSTR_INIT_LITERAL(USERSTREAM_CLOSE, false); + zend_call_method_if_exists(Z_OBJ(us->object), func_name, &retval, 0, NULL); + zend_string_release_ex(func_name, false); zval_ptr_dtor(&retval); - zval_ptr_dtor(&func_name); zval_ptr_dtor(&us->object); ZVAL_UNDEF(&us->object); @@ -712,48 +695,40 @@ static int php_userstreamop_close(php_stream *stream, int close_handle) static int php_userstreamop_flush(php_stream *stream) { - zval func_name; zval retval; - int call_result; php_userstream_data_t *us = (php_userstream_data_t *)stream->abstract; assert(us != NULL); - ZVAL_STRINGL(&func_name, USERSTREAM_FLUSH, sizeof(USERSTREAM_FLUSH)-1); + zend_string *func_name = ZSTR_INIT_LITERAL(USERSTREAM_FLUSH, false); + zend_result call_result = zend_call_method_if_exists(Z_OBJ(us->object), func_name, &retval, 0, NULL); + zend_string_release_ex(func_name, false); - call_result = call_method_if_exists(&us->object, &func_name, &retval, 0, NULL); - - if (call_result == SUCCESS && Z_TYPE(retval) != IS_UNDEF && zval_is_true(&retval)) - call_result = 0; - else - call_result = -1; + int ret = call_result == SUCCESS && Z_TYPE(retval) != IS_UNDEF && zval_is_true(&retval) ? 0 : -1; zval_ptr_dtor(&retval); - zval_ptr_dtor(&func_name); - return call_result; + return ret; } static int php_userstreamop_seek(php_stream *stream, zend_off_t offset, int whence, zend_off_t *newoffs) { - zval func_name; zval retval; - int call_result, ret; + int ret; php_userstream_data_t *us = (php_userstream_data_t *)stream->abstract; zval args[2]; assert(us != NULL); - ZVAL_STRINGL(&func_name, USERSTREAM_SEEK, sizeof(USERSTREAM_SEEK)-1); - ZVAL_LONG(&args[0], offset); ZVAL_LONG(&args[1], whence); - call_result = call_method_if_exists(&us->object, &func_name, &retval, 2, args); + zend_string *func_name = ZSTR_INIT_LITERAL(USERSTREAM_SEEK, false); + zend_result call_result = zend_call_method_if_exists(Z_OBJ(us->object), func_name, &retval, 2, args); + zend_string_release_ex(func_name, false); zval_ptr_dtor(&args[0]); zval_ptr_dtor(&args[1]); - zval_ptr_dtor(&func_name); if (call_result == FAILURE) { /* stream_seek is not implemented, so disable seeks for this stream */ @@ -777,14 +752,14 @@ static int php_userstreamop_seek(php_stream *stream, zend_off_t offset, int when } /* now determine where we are */ - ZVAL_STRINGL(&func_name, USERSTREAM_TELL, sizeof(USERSTREAM_TELL)-1); - - call_result = call_method_if_exists(&us->object, &func_name, &retval, 0, NULL); + func_name = ZSTR_INIT_LITERAL(USERSTREAM_TELL, false); + call_result = zend_call_method_if_exists(Z_OBJ(us->object), func_name, &retval, 0, NULL); + zend_string_release_ex(func_name, false); if (call_result == SUCCESS && Z_TYPE(retval) == IS_LONG) { *newoffs = Z_LVAL(retval); ret = 0; - } else if (call_result == FAILURE) { + } else if (UNEXPECTED(call_result == FAILURE)) { php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_TELL " is not implemented!", ZSTR_VAL(us->wrapper->ce->name)); ret = -1; } else { @@ -792,18 +767,17 @@ static int php_userstreamop_seek(php_stream *stream, zend_off_t offset, int when } zval_ptr_dtor(&retval); - zval_ptr_dtor(&func_name); return ret; } /* parse the return value from one of the stat functions and store the * relevant fields into the statbuf provided */ -static void statbuf_from_array(zval *array, php_stream_statbuf *ssb) +static void statbuf_from_array(const HashTable *array, php_stream_statbuf *ssb) { zval *elem; #define STAT_PROP_ENTRY_EX(name, name2) \ - if (NULL != (elem = zend_hash_str_find(Z_ARRVAL_P(array), #name, sizeof(#name)-1))) { \ + if (NULL != (elem = zend_hash_str_find(array, #name, sizeof(#name)-1))) { \ ssb->sb.st_##name2 = zval_get_long(elem); \ } @@ -836,205 +810,240 @@ static void statbuf_from_array(zval *array, php_stream_statbuf *ssb) static int php_userstreamop_stat(php_stream *stream, php_stream_statbuf *ssb) { - zval func_name; zval retval; - int call_result; php_userstream_data_t *us = (php_userstream_data_t *)stream->abstract; int ret = -1; - ZVAL_STRINGL(&func_name, USERSTREAM_STAT, sizeof(USERSTREAM_STAT)-1); + zend_string *func_name = ZSTR_INIT_LITERAL(USERSTREAM_STAT, false); + zend_result call_result = zend_call_method_if_exists(Z_OBJ(us->object), func_name, &retval, 0, NULL); + zend_string_release_ex(func_name, false); - call_result = call_method_if_exists(&us->object, &func_name, &retval, 0, NULL); - - if (call_result == SUCCESS && Z_TYPE(retval) == IS_ARRAY) { - statbuf_from_array(&retval, ssb); - ret = 0; - } else { - if (call_result == FAILURE) { - php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_STAT " is not implemented!", - ZSTR_VAL(us->wrapper->ce->name)); - } + if (UNEXPECTED(call_result == FAILURE)) { + php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_STAT " is not implemented!", + ZSTR_VAL(us->wrapper->ce->name)); + return -1; + } + if (UNEXPECTED(Z_ISUNDEF(retval))) { + return -1; } + if (EXPECTED(Z_TYPE(retval) == IS_ARRAY)) { + statbuf_from_array(Z_ARR(retval), ssb); + ret = 0; + } + // TODO: Warning on incorrect return type? + zval_ptr_dtor(&retval); - zval_ptr_dtor(&func_name); return ret; } - -static int php_userstreamop_set_option(php_stream *stream, int option, int value, void *ptrparam) { - zval func_name; +static int user_stream_set_check_liveliness(const php_userstream_data_t *us) +{ zval retval; - int call_result; - php_userstream_data_t *us = (php_userstream_data_t *)stream->abstract; - int ret = PHP_STREAM_OPTION_RETURN_NOTIMPL; - zval args[3]; - switch (option) { - case PHP_STREAM_OPTION_CHECK_LIVENESS: - ZVAL_STRINGL(&func_name, USERSTREAM_EOF, sizeof(USERSTREAM_EOF)-1); - call_result = call_method_if_exists(&us->object, &func_name, &retval, 0, NULL); - if (call_result == SUCCESS && (Z_TYPE(retval) == IS_FALSE || Z_TYPE(retval) == IS_TRUE)) { - ret = zval_is_true(&retval) ? PHP_STREAM_OPTION_RETURN_ERR : PHP_STREAM_OPTION_RETURN_OK; - } else { - ret = PHP_STREAM_OPTION_RETURN_ERR; - php_error_docref(NULL, E_WARNING, - "%s::" USERSTREAM_EOF " is not implemented! Assuming EOF", - ZSTR_VAL(us->wrapper->ce->name)); - } + zend_string *func_name = ZSTR_INIT_LITERAL(USERSTREAM_EOF, false); + zend_result call_result = zend_call_method_if_exists(Z_OBJ(us->object), func_name, &retval, 0, NULL); + zend_string_release_ex(func_name, false); + + if (UNEXPECTED(call_result == FAILURE)) { + php_error_docref(NULL, E_WARNING, + "%s::" USERSTREAM_EOF " is not implemented! Assuming EOF", + ZSTR_VAL(us->wrapper->ce->name)); + return PHP_STREAM_OPTION_RETURN_ERR; + } + if (UNEXPECTED(Z_ISUNDEF(retval))) { + return PHP_STREAM_OPTION_RETURN_ERR; + } + if (EXPECTED(Z_TYPE(retval) == IS_FALSE || Z_TYPE(retval) == IS_TRUE)) { + return Z_TYPE(retval) == IS_TRUE ? PHP_STREAM_OPTION_RETURN_ERR : PHP_STREAM_OPTION_RETURN_OK; + } else { + php_error_docref(NULL, E_WARNING, + "%s::" USERSTREAM_EOF " value must be of type bool, %s given", + ZSTR_VAL(us->wrapper->ce->name), zend_zval_value_name(&retval)); zval_ptr_dtor(&retval); - zval_ptr_dtor(&func_name); - break; + return PHP_STREAM_OPTION_RETURN_ERR; + } +} - case PHP_STREAM_OPTION_LOCKING: - ZVAL_LONG(&args[0], 0); +static int user_stream_set_locking(const php_userstream_data_t *us, int value) +{ + zval retval; + zval zlock; + zend_long lock = 0; - if (value & LOCK_NB) { - Z_LVAL_P(&args[0]) |= PHP_LOCK_NB; - } - switch(value & ~LOCK_NB) { + if (value & LOCK_NB) { + lock |= PHP_LOCK_NB; + } + switch (value & ~LOCK_NB) { case LOCK_SH: - Z_LVAL_P(&args[0]) |= PHP_LOCK_SH; + lock |= PHP_LOCK_SH; break; case LOCK_EX: - Z_LVAL_P(&args[0]) |= PHP_LOCK_EX; + lock |= PHP_LOCK_EX; break; case LOCK_UN: - Z_LVAL_P(&args[0]) |= PHP_LOCK_UN; - break; - } - - /* TODO wouldblock */ - ZVAL_STRINGL(&func_name, USERSTREAM_LOCK, sizeof(USERSTREAM_LOCK)-1); - - call_result = call_method_if_exists(&us->object, &func_name, &retval, 1, args); - - if (call_result == SUCCESS && (Z_TYPE(retval) == IS_FALSE || Z_TYPE(retval) == IS_TRUE)) { - ret = (Z_TYPE(retval) == IS_FALSE); - } else if (call_result == FAILURE) { - if (value == 0) { - /* lock support test (TODO: more check) */ - ret = PHP_STREAM_OPTION_RETURN_OK; - } else { - php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_LOCK " is not implemented!", - ZSTR_VAL(us->wrapper->ce->name)); - ret = PHP_STREAM_OPTION_RETURN_ERR; - } - } - - zval_ptr_dtor(&retval); - zval_ptr_dtor(&func_name); - zval_ptr_dtor(&args[0]); - break; - - case PHP_STREAM_OPTION_TRUNCATE_API: - ZVAL_STRINGL(&func_name, USERSTREAM_TRUNCATE, sizeof(USERSTREAM_TRUNCATE)-1); - - switch (value) { - case PHP_STREAM_TRUNCATE_SUPPORTED: - if (zend_is_callable_ex(&func_name, Z_OBJ(us->object), IS_CALLABLE_SUPPRESS_DEPRECATIONS, NULL, NULL, NULL)) - ret = PHP_STREAM_OPTION_RETURN_OK; - else - ret = PHP_STREAM_OPTION_RETURN_ERR; - break; - - case PHP_STREAM_TRUNCATE_SET_SIZE: { - ptrdiff_t new_size = *(ptrdiff_t*) ptrparam; - if (new_size >= 0 && new_size <= (ptrdiff_t)LONG_MAX) { - ZVAL_LONG(&args[0], (zend_long)new_size); - call_result = call_method_if_exists(&us->object, &func_name, &retval, 1, args); - if (call_result == SUCCESS && Z_TYPE(retval) != IS_UNDEF) { - if (Z_TYPE(retval) == IS_FALSE || Z_TYPE(retval) == IS_TRUE) { - ret = (Z_TYPE(retval) == IS_TRUE) ? PHP_STREAM_OPTION_RETURN_OK : - PHP_STREAM_OPTION_RETURN_ERR; - } else { - php_error_docref(NULL, E_WARNING, - "%s::" USERSTREAM_TRUNCATE " did not return a boolean!", - ZSTR_VAL(us->wrapper->ce->name)); - } - } else { - php_error_docref(NULL, E_WARNING, - "%s::" USERSTREAM_TRUNCATE " is not implemented!", - ZSTR_VAL(us->wrapper->ce->name)); - } - zval_ptr_dtor(&retval); - zval_ptr_dtor(&args[0]); - } else { /* bad new size */ - ret = PHP_STREAM_OPTION_RETURN_ERR; - } - break; - } - } - zval_ptr_dtor(&func_name); - break; - - case PHP_STREAM_OPTION_READ_BUFFER: - case PHP_STREAM_OPTION_WRITE_BUFFER: - case PHP_STREAM_OPTION_READ_TIMEOUT: - case PHP_STREAM_OPTION_BLOCKING: { - - ZVAL_STRINGL(&func_name, USERSTREAM_SET_OPTION, sizeof(USERSTREAM_SET_OPTION)-1); - - ZVAL_LONG(&args[0], option); - ZVAL_NULL(&args[1]); - ZVAL_NULL(&args[2]); - - switch(option) { - case PHP_STREAM_OPTION_READ_BUFFER: - case PHP_STREAM_OPTION_WRITE_BUFFER: - ZVAL_LONG(&args[1], value); - if (ptrparam) { - ZVAL_LONG(&args[2], *(long *)ptrparam); - } else { - ZVAL_LONG(&args[2], BUFSIZ); - } - break; - case PHP_STREAM_OPTION_READ_TIMEOUT: { - struct timeval tv = *(struct timeval*)ptrparam; - ZVAL_LONG(&args[1], tv.tv_sec); - ZVAL_LONG(&args[2], tv.tv_usec); - break; - } - case PHP_STREAM_OPTION_BLOCKING: - ZVAL_LONG(&args[1], value); + lock |= PHP_LOCK_UN; break; default: - break; + // TODO: Warn on invalid option value? + ; + } + ZVAL_LONG(&zlock, lock); + + /* TODO wouldblock */ + zend_string *func_name = ZSTR_INIT_LITERAL(USERSTREAM_LOCK, false); + zend_result call_result = zend_call_method_if_exists(Z_OBJ(us->object), func_name, &retval, 1, &zlock); + zend_string_release_ex(func_name, false); + + if (UNEXPECTED(call_result == FAILURE)) { + if (value == 0) { + /* lock support test (TODO: more check) */ + return PHP_STREAM_OPTION_RETURN_OK; } + php_error_docref(NULL, E_WARNING, + "%s::" USERSTREAM_LOCK " is not implemented!", + ZSTR_VAL(us->wrapper->ce->name)); + return PHP_STREAM_OPTION_RETURN_ERR; + } + if (UNEXPECTED(Z_ISUNDEF(retval))) { + return PHP_STREAM_OPTION_RETURN_ERR; + } + if (EXPECTED(Z_TYPE(retval) == IS_FALSE || Z_TYPE(retval) == IS_TRUE)) { + // This is somewhat confusing and relies on magic numbers. + return Z_TYPE(retval) == IS_FALSE; + } + // TODO: ext/standard/tests/file/userstreams_004.phpt returns null implicitly for function + // Should this warn or not? And should this be considered an error? + //php_error_docref(NULL, E_WARNING, + // "%s::" USERSTREAM_LOCK " value must be of type bool, %s given", + // ZSTR_VAL(us->wrapper->ce->name), zend_zval_value_name(&retval)); + zval_ptr_dtor(&retval); + return PHP_STREAM_OPTION_RETURN_NOTIMPL; +} - call_result = call_method_if_exists(&us->object, &func_name, &retval, 3, args); +static int user_stream_set_truncation(const php_userstream_data_t *us, int value, void *ptrparam) { + zend_string *func_name = ZSTR_INIT_LITERAL(USERSTREAM_TRUNCATE, false); - if (call_result == FAILURE) { - php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_SET_OPTION " is not implemented!", - ZSTR_VAL(us->wrapper->ce->name)); - ret = PHP_STREAM_OPTION_RETURN_ERR; - } else if (zend_is_true(&retval)) { - ret = PHP_STREAM_OPTION_RETURN_OK; - } else { - ret = PHP_STREAM_OPTION_RETURN_ERR; - } + if (value == PHP_STREAM_TRUNCATE_SUPPORTED) { + zval zstr; + ZVAL_STR(&zstr, func_name); + bool is_callable = zend_is_callable_ex(&zstr, Z_OBJ(us->object), IS_CALLABLE_SUPPRESS_DEPRECATIONS, NULL, NULL, NULL); + // Frees func_name + zval_ptr_dtor(&zstr); + return is_callable ? PHP_STREAM_OPTION_RETURN_OK : PHP_STREAM_OPTION_RETURN_ERR; + } + ZEND_ASSERT(value == PHP_STREAM_TRUNCATE_SET_SIZE); + ptrdiff_t new_size = *(ptrdiff_t*) ptrparam; + if (UNEXPECTED(new_size < 0 || new_size > (ptrdiff_t)LONG_MAX)) { + /* bad new size */ + zend_string_release_ex(func_name, false); + return PHP_STREAM_OPTION_RETURN_ERR; + } + + zval retval; + zval size; + + ZVAL_LONG(&size, (zend_long)new_size); + zend_result call_result = zend_call_method_if_exists(Z_OBJ(us->object), func_name, &retval, 1, &size); + zend_string_release_ex(func_name, false); + + if (UNEXPECTED(call_result == FAILURE)) { + php_error_docref(NULL, E_WARNING, + "%s::" USERSTREAM_TRUNCATE " is not implemented!", + ZSTR_VAL(us->wrapper->ce->name)); + return PHP_STREAM_OPTION_RETURN_ERR; + } + if (UNEXPECTED(Z_ISUNDEF(retval))) { + return PHP_STREAM_OPTION_RETURN_ERR; + } + if (EXPECTED(Z_TYPE(retval) == IS_FALSE || Z_TYPE(retval) == IS_TRUE)) { + return Z_TYPE(retval) == IS_TRUE ? PHP_STREAM_OPTION_RETURN_OK : PHP_STREAM_OPTION_RETURN_ERR; + } else { + php_error_docref(NULL, E_WARNING, + "%s::" USERSTREAM_TRUNCATE " value must be of type bool, %s given", + ZSTR_VAL(us->wrapper->ce->name), zend_zval_value_name(&retval)); zval_ptr_dtor(&retval); - zval_ptr_dtor(&args[2]); - zval_ptr_dtor(&args[1]); - zval_ptr_dtor(&args[0]); - zval_ptr_dtor(&func_name); + return PHP_STREAM_OPTION_RETURN_ERR; + } +} - break; +static int user_stream_set_option(const php_userstream_data_t *us, int option, int value, void *ptrparam) +{ + zval args[3]; + ZVAL_LONG(&args[0], option); + ZVAL_LONG(&args[1], value); + ZVAL_NULL(&args[2]); + + if (option == PHP_STREAM_OPTION_READ_TIMEOUT) { + struct timeval tv = *(struct timeval*)ptrparam; + ZVAL_LONG(&args[1], tv.tv_sec); + ZVAL_LONG(&args[2], tv.tv_usec); + } else if (option == PHP_STREAM_OPTION_READ_BUFFER || option == PHP_STREAM_OPTION_WRITE_BUFFER) { + if (ptrparam) { + ZVAL_LONG(&args[2], *(long *)ptrparam); + } else { + ZVAL_LONG(&args[2], BUFSIZ); } } + zval retval; + zend_string *func_name = ZSTR_INIT_LITERAL(USERSTREAM_SET_OPTION, false); + zend_result call_result = zend_call_method_if_exists(Z_OBJ(us->object), func_name, &retval, 3, args); + zend_string_release_ex(func_name, false); + + if (UNEXPECTED(call_result == FAILURE)) { + php_error_docref(NULL, E_WARNING, + "%s::" USERSTREAM_SET_OPTION " is not implemented!", + ZSTR_VAL(us->wrapper->ce->name)); + return PHP_STREAM_OPTION_RETURN_ERR; + } + if (UNEXPECTED(Z_ISUNDEF(retval))) { + return PHP_STREAM_OPTION_RETURN_ERR; + } + + int ret; + if (zend_is_true(&retval)) { + ret = PHP_STREAM_OPTION_RETURN_OK; + } else { + ret = PHP_STREAM_OPTION_RETURN_ERR; + } + + zval_ptr_dtor(&retval); return ret; } +static int php_userstreamop_set_option(php_stream *stream, int option, int value, void *ptrparam) { + php_userstream_data_t *us = (php_userstream_data_t *)stream->abstract; + + switch (option) { + case PHP_STREAM_OPTION_CHECK_LIVENESS: + return user_stream_set_check_liveliness(us); + + case PHP_STREAM_OPTION_LOCKING: + return user_stream_set_locking(us, value); + + case PHP_STREAM_OPTION_TRUNCATE_API: + return user_stream_set_truncation(us, value, ptrparam); + + case PHP_STREAM_OPTION_READ_BUFFER: + case PHP_STREAM_OPTION_WRITE_BUFFER: + case PHP_STREAM_OPTION_READ_TIMEOUT: + case PHP_STREAM_OPTION_BLOCKING: + return user_stream_set_option(us, option, value, ptrparam); + + default: + return PHP_STREAM_OPTION_RETURN_NOTIMPL; + } +} + static int user_wrapper_unlink(php_stream_wrapper *wrapper, const char *url, int options, php_stream_context *context) { struct php_user_stream_wrapper *uwrap = (struct php_user_stream_wrapper*)wrapper->abstract; - zval zfuncname, zretval; + zval zretval; zval args[1]; - int call_result; zval object; int ret = 0; @@ -1047,22 +1056,21 @@ static int user_wrapper_unlink(php_stream_wrapper *wrapper, const char *url, int /* call the unlink method */ ZVAL_STRING(&args[0], url); - ZVAL_STRING(&zfuncname, USERSTREAM_UNLINK); - - call_result = call_method_if_exists(&object, &zfuncname, &zretval, 1, args); - - if (call_result == SUCCESS && (Z_TYPE(zretval) == IS_FALSE || Z_TYPE(zretval) == IS_TRUE)) { - ret = (Z_TYPE(zretval) == IS_TRUE); - } else if (call_result == FAILURE) { - php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_UNLINK " is not implemented!", ZSTR_VAL(uwrap->ce->name)); - } - - /* clean up */ - zval_ptr_dtor(&object); - zval_ptr_dtor(&zretval); - zval_ptr_dtor(&zfuncname); + zend_string *func_name = ZSTR_INIT_LITERAL(USERSTREAM_UNLINK, false); + zend_result call_result = zend_call_method_if_exists(Z_OBJ(object), func_name, &zretval, 1, args); + zend_string_release_ex(func_name, false); zval_ptr_dtor(&args[0]); + zval_ptr_dtor(&object); + + if (UNEXPECTED(call_result == FAILURE)) { + php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_UNLINK " is not implemented!", ZSTR_VAL(uwrap->ce->name)); + } else if (Z_TYPE(zretval) == IS_FALSE || Z_TYPE(zretval) == IS_TRUE) { + ret = Z_TYPE(zretval) == IS_TRUE; + } + // TODO: Warn on invalid return type, or use zval_is_true()? + + zval_ptr_dtor(&zretval); return ret; } @@ -1071,9 +1079,8 @@ static int user_wrapper_rename(php_stream_wrapper *wrapper, const char *url_from int options, php_stream_context *context) { struct php_user_stream_wrapper *uwrap = (struct php_user_stream_wrapper*)wrapper->abstract; - zval zfuncname, zretval; + zval zretval; zval args[2]; - int call_result; zval object; int ret = 0; @@ -1087,23 +1094,21 @@ static int user_wrapper_rename(php_stream_wrapper *wrapper, const char *url_from ZVAL_STRING(&args[0], url_from); ZVAL_STRING(&args[1], url_to); - ZVAL_STRING(&zfuncname, USERSTREAM_RENAME); - - call_result = call_method_if_exists(&object, &zfuncname, &zretval, 2, args); - - if (call_result == SUCCESS && (Z_TYPE(zretval) == IS_FALSE || Z_TYPE(zretval) == IS_TRUE)) { - ret = (Z_TYPE(zretval) == IS_TRUE); - } else if (call_result == FAILURE) { - php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_RENAME " is not implemented!", ZSTR_VAL(uwrap->ce->name)); - } - - /* clean up */ - zval_ptr_dtor(&object); - zval_ptr_dtor(&zretval); - - zval_ptr_dtor(&zfuncname); + zend_string *func_name = ZSTR_INIT_LITERAL(USERSTREAM_RENAME, false); + zend_result call_result = zend_call_method_if_exists(Z_OBJ(object), func_name, &zretval, 2, args); + zend_string_release_ex(func_name, false); zval_ptr_dtor(&args[1]); zval_ptr_dtor(&args[0]); + zval_ptr_dtor(&object); + + if (UNEXPECTED(call_result == FAILURE)) { + php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_RENAME " is not implemented!", ZSTR_VAL(uwrap->ce->name)); + } else if (Z_TYPE(zretval) == IS_FALSE || Z_TYPE(zretval) == IS_TRUE) { + ret = Z_TYPE(zretval) == IS_TRUE; + } + // TODO: Warn on invalid return type, or use zval_is_true()? + + zval_ptr_dtor(&zretval); return ret; } @@ -1112,9 +1117,8 @@ static int user_wrapper_mkdir(php_stream_wrapper *wrapper, const char *url, int int options, php_stream_context *context) { struct php_user_stream_wrapper *uwrap = (struct php_user_stream_wrapper*)wrapper->abstract; - zval zfuncname, zretval; + zval zretval; zval args[3]; - int call_result; zval object; int ret = 0; @@ -1129,24 +1133,20 @@ static int user_wrapper_mkdir(php_stream_wrapper *wrapper, const char *url, int ZVAL_LONG(&args[1], mode); ZVAL_LONG(&args[2], options); - ZVAL_STRING(&zfuncname, USERSTREAM_MKDIR); - - call_result = call_method_if_exists(&object, &zfuncname, &zretval, 3, args); - - if (call_result == SUCCESS && (Z_TYPE(zretval) == IS_FALSE || Z_TYPE(zretval) == IS_TRUE)) { - ret = (Z_TYPE(zretval) == IS_TRUE); - } else if (call_result == FAILURE) { - php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_MKDIR " is not implemented!", ZSTR_VAL(uwrap->ce->name)); - } - - /* clean up */ - zval_ptr_dtor(&object); - zval_ptr_dtor(&zretval); - - zval_ptr_dtor(&zfuncname); - zval_ptr_dtor(&args[2]); - zval_ptr_dtor(&args[1]); + zend_string *func_name = ZSTR_INIT_LITERAL(USERSTREAM_MKDIR, false); + zend_result call_result = zend_call_method_if_exists(Z_OBJ(object), func_name, &zretval, 3, args); + zend_string_release_ex(func_name, false); zval_ptr_dtor(&args[0]); + zval_ptr_dtor(&object); + + if (UNEXPECTED(call_result == FAILURE)) { + php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_MKDIR " is not implemented!", ZSTR_VAL(uwrap->ce->name)); + } else if (Z_TYPE(zretval) == IS_FALSE || Z_TYPE(zretval) == IS_TRUE) { + ret = Z_TYPE(zretval) == IS_TRUE; + } + // TODO: Warn on invalid return type, or use zval_is_true()? + + zval_ptr_dtor(&zretval); return ret; } @@ -1155,9 +1155,8 @@ static int user_wrapper_rmdir(php_stream_wrapper *wrapper, const char *url, int options, php_stream_context *context) { struct php_user_stream_wrapper *uwrap = (struct php_user_stream_wrapper*)wrapper->abstract; - zval zfuncname, zretval; + zval zretval; zval args[2]; - int call_result; zval object; int ret = 0; @@ -1171,23 +1170,20 @@ static int user_wrapper_rmdir(php_stream_wrapper *wrapper, const char *url, ZVAL_STRING(&args[0], url); ZVAL_LONG(&args[1], options); - ZVAL_STRING(&zfuncname, USERSTREAM_RMDIR); - - call_result = call_method_if_exists(&object, &zfuncname, &zretval, 2, args); - - if (call_result == SUCCESS && (Z_TYPE(zretval) == IS_FALSE || Z_TYPE(zretval) == IS_TRUE)) { - ret = (Z_TYPE(zretval) == IS_TRUE); - } else if (call_result == FAILURE) { - php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_RMDIR " is not implemented!", ZSTR_VAL(uwrap->ce->name)); - } - - /* clean up */ - zval_ptr_dtor(&object); - zval_ptr_dtor(&zretval); - - zval_ptr_dtor(&zfuncname); - zval_ptr_dtor(&args[1]); + zend_string *func_name = ZSTR_INIT_LITERAL(USERSTREAM_RMDIR, false); + zend_result call_result = zend_call_method_if_exists(Z_OBJ(object), func_name, &zretval, 2, args); + zend_string_release_ex(func_name, false); zval_ptr_dtor(&args[0]); + zval_ptr_dtor(&object); + + if (UNEXPECTED(call_result == FAILURE)) { + php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_RMDIR " is not implemented!", ZSTR_VAL(uwrap->ce->name)); + } else if (Z_TYPE(zretval) == IS_FALSE || Z_TYPE(zretval) == IS_TRUE) { + ret = Z_TYPE(zretval) == IS_TRUE; + } + // TODO: Warn on invalid return type, or use zval_is_true()? + + zval_ptr_dtor(&zretval); return ret; } @@ -1196,9 +1192,8 @@ static int user_wrapper_metadata(php_stream_wrapper *wrapper, const char *url, i void *value, php_stream_context *context) { struct php_user_stream_wrapper *uwrap = (struct php_user_stream_wrapper*)wrapper->abstract; - zval zfuncname, zretval; + zval zretval; zval args[3]; - int call_result; zval object; int ret = 0; @@ -1237,24 +1232,21 @@ static int user_wrapper_metadata(php_stream_wrapper *wrapper, const char *url, i ZVAL_STRING(&args[0], url); ZVAL_LONG(&args[1], option); - ZVAL_STRING(&zfuncname, USERSTREAM_METADATA); - - call_result = call_method_if_exists(&object, &zfuncname, &zretval, 3, args); - - if (call_result == SUCCESS && (Z_TYPE(zretval) == IS_FALSE || Z_TYPE(zretval) == IS_TRUE)) { - ret = Z_TYPE(zretval) == IS_TRUE; - } else if (call_result == FAILURE) { - php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_METADATA " is not implemented!", ZSTR_VAL(uwrap->ce->name)); - } - - /* clean up */ - zval_ptr_dtor(&object); - zval_ptr_dtor(&zretval); - - zval_ptr_dtor(&zfuncname); - zval_ptr_dtor(&args[0]); - zval_ptr_dtor(&args[1]); + zend_string *func_name = ZSTR_INIT_LITERAL(USERSTREAM_METADATA, false); + zend_result call_result = zend_call_method_if_exists(Z_OBJ(object), func_name, &zretval, 3, args); + zend_string_release_ex(func_name, false); zval_ptr_dtor(&args[2]); + zval_ptr_dtor(&args[0]); + zval_ptr_dtor(&object); + + if (UNEXPECTED(call_result == FAILURE)) { + php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_METADATA " is not implemented!", ZSTR_VAL(uwrap->ce->name)); + } else if (Z_TYPE(zretval) == IS_FALSE || Z_TYPE(zretval) == IS_TRUE) { + ret = Z_TYPE(zretval) == IS_TRUE; + } + // TODO: Warn on invalid return type, or use zval_is_true()? + + zval_ptr_dtor(&zretval); return ret; } @@ -1264,44 +1256,42 @@ static int user_wrapper_stat_url(php_stream_wrapper *wrapper, const char *url, i php_stream_statbuf *ssb, php_stream_context *context) { struct php_user_stream_wrapper *uwrap = (struct php_user_stream_wrapper*)wrapper->abstract; - zval zfuncname, zretval; + zval zretval; zval args[2]; - int call_result; zval object; int ret = -1; /* create an instance of our class */ user_stream_create_object(uwrap, context, &object); if (Z_TYPE(object) == IS_UNDEF) { - return ret; + return -1; } /* call it's stat_url method - set up params first */ ZVAL_STRING(&args[0], url); ZVAL_LONG(&args[1], flags); - ZVAL_STRING(&zfuncname, USERSTREAM_STATURL); - - call_result = call_method_if_exists(&object, &zfuncname, &zretval, 2, args); - - if (call_result == SUCCESS && Z_TYPE(zretval) == IS_ARRAY) { - /* We got the info we needed */ - statbuf_from_array(&zretval, ssb); - ret = 0; - } else { - if (call_result == FAILURE) { - php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_STATURL " is not implemented!", - ZSTR_VAL(uwrap->ce->name)); - } - } - - /* clean up */ - zval_ptr_dtor(&object); - zval_ptr_dtor(&zretval); - - zval_ptr_dtor(&zfuncname); - zval_ptr_dtor(&args[1]); + zend_string *func_name = ZSTR_INIT_LITERAL(USERSTREAM_STATURL, false); + zend_result call_result = zend_call_method_if_exists(Z_OBJ(object), func_name, &zretval, 2, args); + zend_string_release_ex(func_name, false); zval_ptr_dtor(&args[0]); + zval_ptr_dtor(&object); + + if (UNEXPECTED(call_result == FAILURE)) { + php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_STATURL " is not implemented!", + ZSTR_VAL(uwrap->ce->name)); + return -1; + } + if (UNEXPECTED(Z_ISUNDEF(zretval))) { + return -1; + } + if (EXPECTED(Z_TYPE(zretval) == IS_ARRAY)) { + statbuf_from_array(Z_ARR(zretval), ssb); + ret = 0; + } + // TODO: Warning on incorrect return type? + + zval_ptr_dtor(&zretval); return ret; @@ -1309,55 +1299,62 @@ static int user_wrapper_stat_url(php_stream_wrapper *wrapper, const char *url, i static ssize_t php_userstreamop_readdir(php_stream *stream, char *buf, size_t count) { - zval func_name; zval retval; - int call_result; size_t didread = 0; php_userstream_data_t *us = (php_userstream_data_t *)stream->abstract; php_stream_dirent *ent = (php_stream_dirent*)buf; /* avoid problems if someone mis-uses the stream */ - if (count != sizeof(php_stream_dirent)) + if (count != sizeof(php_stream_dirent)) { return -1; + } - ZVAL_STRINGL(&func_name, USERSTREAM_DIR_READ, sizeof(USERSTREAM_DIR_READ)-1); + zend_string *func_name = ZSTR_INIT_LITERAL(USERSTREAM_DIR_READ, false); + zend_result call_result = zend_call_method_if_exists(Z_OBJ(us->object), func_name, &retval, 0, NULL); + zend_string_release_ex(func_name, false); - call_result = call_method_if_exists(&us->object, &func_name, &retval, 0, NULL); - - if (call_result == SUCCESS && Z_TYPE(retval) != IS_FALSE && Z_TYPE(retval) != IS_TRUE) { + if (UNEXPECTED(call_result == FAILURE)) { + php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_DIR_READ " is not implemented!", + ZSTR_VAL(us->wrapper->ce->name)); + return -1; + } + if (UNEXPECTED(Z_ISUNDEF(retval))) { + return -1; + } + // TODO: Warn/TypeError for invalid returns? + if (Z_TYPE(retval) != IS_FALSE && Z_TYPE(retval) != IS_TRUE) { + zend_string *str = zval_try_get_string(&retval); + if (UNEXPECTED(str == NULL)) { + zval_ptr_dtor(&retval); + return -1; + } convert_to_string(&retval); - PHP_STRLCPY(ent->d_name, Z_STRVAL(retval), sizeof(ent->d_name), Z_STRLEN(retval)); + PHP_STRLCPY(ent->d_name, ZSTR_VAL(str), sizeof(ent->d_name), ZSTR_LEN(str)); + zend_string_release(str); ent->d_type = DT_UNKNOWN; didread = sizeof(php_stream_dirent); - } else if (call_result == FAILURE) { - php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_DIR_READ " is not implemented!", - ZSTR_VAL(us->wrapper->ce->name)); } zval_ptr_dtor(&retval); - zval_ptr_dtor(&func_name); return didread; } static int php_userstreamop_closedir(php_stream *stream, int close_handle) { - zval func_name; zval retval; php_userstream_data_t *us = (php_userstream_data_t *)stream->abstract; assert(us != NULL); - ZVAL_STRINGL(&func_name, USERSTREAM_DIR_CLOSE, sizeof(USERSTREAM_DIR_CLOSE)-1); - - call_method_if_exists(&us->object, &func_name, &retval, 0, NULL); + zend_string *func_name = ZSTR_INIT_LITERAL(USERSTREAM_DIR_CLOSE, false); + zend_call_method_if_exists(Z_OBJ(us->object), func_name, &retval, 0, NULL); + zend_string_release_ex(func_name, false); zval_ptr_dtor(&retval); - zval_ptr_dtor(&func_name); zval_ptr_dtor(&us->object); ZVAL_UNDEF(&us->object); - efree(us); return 0; @@ -1365,16 +1362,14 @@ static int php_userstreamop_closedir(php_stream *stream, int close_handle) static int php_userstreamop_rewinddir(php_stream *stream, zend_off_t offset, int whence, zend_off_t *newoffs) { - zval func_name; zval retval; php_userstream_data_t *us = (php_userstream_data_t *)stream->abstract; - ZVAL_STRINGL(&func_name, USERSTREAM_DIR_REWIND, sizeof(USERSTREAM_DIR_REWIND)-1); - - call_method_if_exists(&us->object, &func_name, &retval, 0, NULL); + zend_string *func_name = ZSTR_INIT_LITERAL(USERSTREAM_DIR_REWIND, false); + zend_call_method_if_exists(Z_OBJ(us->object), func_name, &retval, 0, NULL); + zend_string_release_ex(func_name, false); zval_ptr_dtor(&retval); - zval_ptr_dtor(&func_name); return 0; @@ -1383,17 +1378,13 @@ static int php_userstreamop_rewinddir(php_stream *stream, zend_off_t offset, int static int php_userstreamop_cast(php_stream *stream, int castas, void **retptr) { php_userstream_data_t *us = (php_userstream_data_t *)stream->abstract; - zval func_name; zval retval; zval args[1]; php_stream * intstream = NULL; - int call_result; int ret = FAILURE; /* If we are checking if the stream can cast, no return pointer is provided, so do not emit errors */ bool report_errors = retptr; - ZVAL_STRINGL(&func_name, USERSTREAM_CAST, sizeof(USERSTREAM_CAST)-1); - switch(castas) { case PHP_STREAM_AS_FD_FOR_SELECT: ZVAL_LONG(&args[0], PHP_STREAM_AS_FD_FOR_SELECT); @@ -1403,19 +1394,23 @@ static int php_userstreamop_cast(php_stream *stream, int castas, void **retptr) break; } - call_result = call_method_if_exists(&us->object, &func_name, &retval, 1, args); + zend_string *func_name = ZSTR_INIT_LITERAL(USERSTREAM_CAST, false); + zend_result call_result = zend_call_method_if_exists(Z_OBJ(us->object), func_name, &retval, 1, args); + zend_string_release_ex(func_name, false); + + if (UNEXPECTED(call_result == FAILURE)) { + if (report_errors) { + php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_CAST " is not implemented!", + ZSTR_VAL(us->wrapper->ce->name)); + } + return FAILURE; + } do { - if (call_result == FAILURE) { - if (report_errors) { - php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_CAST " is not implemented!", - ZSTR_VAL(us->wrapper->ce->name)); - } - break; - } if (!zend_is_true(&retval)) { break; } + // TODO: Can this emit an exception even with no error reporting? php_stream_from_zval_no_verify(intstream, &retval); if (!intstream) { if (report_errors) { @@ -1436,8 +1431,6 @@ static int php_userstreamop_cast(php_stream *stream, int castas, void **retptr) } while (0); zval_ptr_dtor(&retval); - zval_ptr_dtor(&func_name); - zval_ptr_dtor(&args[0]); return ret; } diff --git a/main/streams/xp_socket.c b/main/streams/xp_socket.c index 8623c11be00..ae8cf24c392 100644 --- a/main/streams/xp_socket.c +++ b/main/streams/xp_socket.c @@ -80,13 +80,13 @@ retry: if (sock->is_blocked) { int retval; - sock->timeout_event = 0; + sock->timeout_event = false; do { retval = php_pollfd_for(sock->socket, POLLOUT, ptimeout); if (retval == 0) { - sock->timeout_event = 1; + sock->timeout_event = true; break; } @@ -107,8 +107,8 @@ retry: if (!(stream->flags & PHP_STREAM_FLAG_SUPPRESS_ERRORS)) { estr = php_socket_strerror(err, NULL, 0); php_error_docref(NULL, E_NOTICE, - "Send of " ZEND_LONG_FMT " bytes failed with errno=%d %s", - (zend_long)count, err, estr); + "Send of %zu bytes failed with errno=%d %s", + count, err, estr); efree(estr); } } @@ -129,7 +129,7 @@ static void php_sock_stream_wait_for_data(php_stream *stream, php_netstream_data return; } - sock->timeout_event = 0; + sock->timeout_event = false; if (has_buffered_data) { /* If there is already buffered data, use no timeout. */ @@ -146,7 +146,7 @@ static void php_sock_stream_wait_for_data(php_stream *stream, php_netstream_data retval = php_pollfd_for(sock->socket, PHP_POLLREADABLE, ptimeout); if (retval == 0) - sock->timeout_event = 1; + sock->timeout_event = true; if (retval >= 0) break; @@ -399,7 +399,7 @@ static int php_sockop_set_option(php_stream *stream, int option, int value, void case PHP_STREAM_OPTION_READ_TIMEOUT: sock->timeout = *(struct timeval*)ptrparam; - sock->timeout_event = 0; + sock->timeout_event = false; return PHP_STREAM_OPTION_RETURN_OK; case PHP_STREAM_OPTION_META_DATA_API: @@ -857,7 +857,6 @@ out: static inline int php_tcp_sockop_accept(php_stream *stream, php_netstream_data_t *sock, php_stream_xport_param *xparam STREAMS_DC) { - int clisock; bool nodelay = 0; zval *tmpzval = NULL; @@ -869,7 +868,7 @@ static inline int php_tcp_sockop_accept(php_stream *stream, php_netstream_data_t nodelay = 1; } - clisock = php_network_accept_incoming(sock->socket, + php_socket_t clisock = php_network_accept_incoming(sock->socket, xparam->want_textaddr ? &xparam->outputs.textaddr : NULL, xparam->want_addr ? &xparam->outputs.addr : NULL, xparam->want_addr ? &xparam->outputs.addrlen : NULL, @@ -885,7 +884,7 @@ static inline int php_tcp_sockop_accept(php_stream *stream, php_netstream_data_t clisockdata->socket = clisock; #ifdef __linux__ /* O_NONBLOCK is not inherited on Linux */ - clisockdata->is_blocked = 1; + clisockdata->is_blocked = true; #endif xparam->outputs.client = php_stream_alloc_rel(stream->ops, clisockdata, NULL, "r+"); @@ -963,7 +962,7 @@ PHPAPI php_stream *php_stream_generic_socket_factory(const char *proto, size_t p sock = pemalloc(sizeof(php_netstream_data_t), persistent_id ? 1 : 0); memset(sock, 0, sizeof(php_netstream_data_t)); - sock->is_blocked = 1; + sock->is_blocked = true; sock->timeout.tv_sec = FG(default_socket_timeout); sock->timeout.tv_usec = 0; diff --git a/php.ini-development b/php.ini-development index 6ef1f940b2f..12db95597c1 100644 --- a/php.ini-development +++ b/php.ini-development @@ -436,6 +436,7 @@ max_input_time = 60 ; Maximum amount of memory a script may consume ; https://php.net/memory-limit memory_limit = 128M +max_memory_limit = -1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Error handling and logging ; @@ -965,8 +966,6 @@ default_socket_timeout = 60 ;extension=xsl ;extension=zip -;zend_extension=opcache - ;;;;;;;;;;;;;;;;;;; ; Module Settings ; ;;;;;;;;;;;;;;;;;;; @@ -1022,8 +1021,12 @@ cli_server.color = On ; This directive allows you to produce PHP errors when some error ; happens within intl functions. The value is the level of the error produced. ; Default is 0, which does not produce any errors. +; This directive is deprecated. ;intl.error_level = E_WARNING -;intl.use_exceptions = 0 +; If enabled this directive indicates that when an error occurs within an +; intl function a IntlException should be thrown. +; Default is Off, which means errors need to be handled manually. +;intl.use_exceptions = On [sqlite3] ; Directory pointing to SQLite3 extensions @@ -1324,6 +1327,9 @@ session.use_cookies = 1 ; https://php.net/session.cookie-secure ;session.cookie_secure = +; https://php.net/session.cookie-partitioned +;session.cookie_partitioned = 0 + ; This option forces PHP to fetch and use a cookie for storing and maintaining ; the session id. We encourage this operation as it's very helpful in combating ; session hijacking when not specifying and managing your own session id. It is diff --git a/php.ini-production b/php.ini-production index d1b25a34a48..d144f952e72 100644 --- a/php.ini-production +++ b/php.ini-production @@ -438,6 +438,7 @@ max_input_time = 60 ; Maximum amount of memory a script may consume ; https://php.net/memory-limit memory_limit = 128M +max_memory_limit = -1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Error handling and logging ; @@ -967,8 +968,6 @@ default_socket_timeout = 60 ;extension=xsl ;extension=zip -;zend_extension=opcache - ;;;;;;;;;;;;;;;;;;; ; Module Settings ; ;;;;;;;;;;;;;;;;;;; @@ -1024,8 +1023,12 @@ cli_server.color = On ; This directive allows you to produce PHP errors when some error ; happens within intl functions. The value is the level of the error produced. ; Default is 0, which does not produce any errors. +; This directive is deprecated. ;intl.error_level = E_WARNING -;intl.use_exceptions = 0 +; If enabled this directive indicates that when an error occurs within an +; intl function a IntlException should be thrown. +; Default is Off, which means errors need to be handled manually. +;intl.use_exceptions = On [sqlite3] ; Directory pointing to SQLite3 extensions @@ -1326,6 +1329,9 @@ session.use_cookies = 1 ; https://php.net/session.cookie-secure ;session.cookie_secure = +; https://php.net/session.cookie-partitioned +;session.cookie_partitioned = 0 + ; This option forces PHP to fetch and use a cookie for storing and maintaining ; the session id. We encourage this operation as it's very helpful in combating ; session hijacking when not specifying and managing your own session id. It is diff --git a/run-extra-tests.php b/run-extra-tests.php new file mode 100755 index 00000000000..725f2b58c37 --- /dev/null +++ b/run-extra-tests.php @@ -0,0 +1,202 @@ +#!/usr/bin/env php +os}\n"; + echo "CPU Arch: {$environment->cpuArch}\n"; + echo "ZTS: " . ($environment->zts ? 'Yes' : 'No') . "\n"; + echo "DEBUG: " . ($environment->debug ? 'Yes' : 'No') . "\n"; + echo "=====================================================================\n"; + + try { + output_group_start($environment, 'Running Opcache TLS tests'); + if (!run_opcache_tls_tests($environment)) { + echo "Failed\n"; + exit(1); + } + } finally { + output_group_end($environment); + } + + echo "All OK\n"; +} + +function run_opcache_tls_tests(Environment $environment): bool +{ + if (!$environment->zts) { + echo "Skipping: NTS\n"; + return true; + } + + if (!$environment->debug) { + echo "Skipping: NDEBUG\n"; + return true; + } + + $tlsc = ''; + $machine = ''; + $static_support = 'yes'; + + switch ($environment->cpuArch) { + case 'x86': + $machine = '-m32'; + break; + case 'x86_64': + case 'aarch64': + break; + default: + echo "Skipping: {$environment->cpuArch}\n"; + return true; + } + + switch ($environment->os) { + case 'Linux': + case 'FreeBSD': + $tlsc = __DIR__ . "/ext/opcache/jit/tls/zend_jit_tls_{$environment->cpuArch}.c"; + break; + case 'Darwin': + if ($environment->cpuArch === 'aarch64') { + echo "Skipping: JIT+TLS not supported on MacOS Apple Silicon\n"; + return true; + } + $tlsc = __DIR__ . "/ext/opcache/jit/tls/zend_jit_tls_darwin.c"; + $static_support = 'no'; + break; + default: + echo "Skipping: {$environment->os}\n"; + return true; + } + + echo "TLSC=$tlsc MACHINE=$machine STATIC_SUPPORT=$static_support ext/opcache/jit/tls/testing/test.sh\n"; + + $proc = proc_open( + __DIR__ . '/ext/opcache/jit/tls/testing/test.sh', + [ + 0 => ['pipe', 'r'], + ], + $pipes, + env_vars: array_merge(getenv(), [ + 'TLSC' => $tlsc, + 'MACHINE' => $machine, + 'STATIC_SUPPORT' => $static_support, + ]), + ); + + if (!$proc) { + echo "proc_open() failed\n"; + return false; + } + + fclose($pipes[0]); + + return proc_close($proc) === 0; +} + +function output_group_start(Environment $environment, string $name): void +{ + if ($environment->githubAction) { + printf("::group::%s\n", $name); + } else { + printf("%s\n", $name); + } +} + +function output_group_end(Environment $environment): void +{ + if ($environment->githubAction) { + printf("::endgroup::\n"); + } +} + +/** + * Returns getenv('TEST_PHP_OS') if defined, otherwise returns one of + * 'Windows NT', 'Linux', 'FreeBSD', 'Darwin', ... + */ +function detect_os(): string +{ + $os = (string) getenv('TEST_PHP_OS'); + if ($os !== '') { + return $os; + } + + return php_uname('s'); +} + +/** + * Returns getenv('TEST_PHP_CPU_ARCH') if defined, otherwise returns one of + * 'x86', 'x86_64', 'aarch64', ... + */ +function detect_cpu_arch(): string +{ + $cpu = (string) getenv('TEST_PHP_CPU_ARCH'); + if ($cpu !== '') { + return $cpu; + } + + $cpu = php_uname('m'); + if (strtolower($cpu) === 'amd64') { + $cpu = 'x86_64'; + } else if (in_array($cpu, ['i386', 'i686'])) { + $cpu = 'x86'; + } else if ($cpu === 'arm64') { + $cpu = 'aarch64'; + } + + return $cpu; +} + +main($argc, $argv); diff --git a/run-tests.php b/run-tests.php index 03616272567..6c31c1d0187 100755 --- a/run-tests.php +++ b/run-tests.php @@ -688,6 +688,10 @@ function main(): void // Run selected tests. $test_cnt = count($test_files); + if ($test_cnt === 1) { + $cfg['show']['diff'] = true; + } + verify_config($php); write_information($user_tests, $phpdbg); diff --git a/sapi/apache2handler/sapi_apache2.c b/sapi/apache2handler/sapi_apache2.c index e87223b055e..88fc584a8bc 100644 --- a/sapi/apache2handler/sapi_apache2.c +++ b/sapi/apache2handler/sapi_apache2.c @@ -752,6 +752,7 @@ zend_first_try { static void php_apache_child_init(apr_pool_t *pchild, server_rec *s) { apr_pool_cleanup_register(pchild, NULL, php_apache_child_shutdown, apr_pool_cleanup_null); + php_child_init(); } #ifdef ZEND_SIGNALS diff --git a/sapi/cgi/cgi_main.c b/sapi/cgi/cgi_main.c index e3cd6f49b9f..6db96a43ac9 100644 --- a/sapi/cgi/cgi_main.c +++ b/sapi/cgi/cgi_main.c @@ -2041,6 +2041,8 @@ consult the installation file that came with this distribution, or visit \n\ */ parent = 0; + php_child_init(); + /* don't catch our signals */ sigaction(SIGTERM, &old_term, 0); sigaction(SIGQUIT, &old_quit, 0); diff --git a/sapi/cgi/tests/001.phpt b/sapi/cgi/tests/001.phpt index c4b539aa83b..c990a77efae 100644 --- a/sapi/cgi/tests/001.phpt +++ b/sapi/cgi/tests/001.phpt @@ -10,13 +10,12 @@ include "include.inc"; $php = get_cgi_path(); reset_env_vars(); -var_dump(`$php -n -v`); +var_dump(shell_exec("$php -n -v")); echo "Done\n"; ?> --EXPECTF-- string(%d) "PHP %s (cgi%s (built: %s Copyright (c) The PHP Group -%AZend Engine v%s, Copyright (c) Zend Technologies -" +%AZend Engine v%s, Copyright (c) Zend Technologies%A" Done diff --git a/sapi/cgi/tests/002.phpt b/sapi/cgi/tests/002.phpt index b28c8656598..374a427cdce 100644 --- a/sapi/cgi/tests/002.phpt +++ b/sapi/cgi/tests/002.phpt @@ -15,13 +15,13 @@ $file = __DIR__."/002.test.php"; file_put_contents($file, ''); -var_dump(`$php -n -d max_execution_time=111 $file`); -var_dump(`$php -n -d max_execution_time=500 $file`); -var_dump(`$php -n -d max_execution_time=500 -d max_execution_time=555 $file`); +var_dump(shell_exec("$php -n -d max_execution_time=111 $file")); +var_dump(shell_exec("$php -n -d max_execution_time=500 $file")); +var_dump(shell_exec("$php -n -d max_execution_time=500 -d max_execution_time=555 $file")); file_put_contents($file, ''); -var_dump(`$php -n -d upload_tmp_dir=/test/path -d max_execution_time=555 $file`); +var_dump(shell_exec("$php -n -d upload_tmp_dir=/test/path -d max_execution_time=555 $file")); unlink($file); diff --git a/sapi/cgi/tests/003.phpt b/sapi/cgi/tests/003.phpt index ac3f6aa8e63..81d46e868b3 100644 --- a/sapi/cgi/tests/003.phpt +++ b/sapi/cgi/tests/003.phpt @@ -37,9 +37,15 @@ class test { /* {{{ */ file_put_contents($filename, $code); -var_dump(`$php -n -w "$filename"`); -var_dump(`$php -n -w "wrong"`); -var_dump(`echo "" | $php -n -w`); +var_dump(shell_exec(<<" | $php -n -w +SHELL)); @unlink($filename); diff --git a/sapi/cgi/tests/004.phpt b/sapi/cgi/tests/004.phpt index 1de856e3467..fddc5ee80ed 100644 --- a/sapi/cgi/tests/004.phpt +++ b/sapi/cgi/tests/004.phpt @@ -27,11 +27,17 @@ var_dump(test::$pri); file_put_contents($filename, $code); if (defined("PHP_WINDOWS_VERSION_MAJOR")) { - var_dump(`$php -n -f "$filename"`); + var_dump(shell_exec(<</dev/null`); + var_dump(shell_exec(<</dev/null + SHELL)); } -var_dump(`$php -n -f "wrong"`); +var_dump(shell_exec(<< diff --git a/sapi/cgi/tests/006.phpt b/sapi/cgi/tests/006.phpt index 479d4a9441f..840dd432977 100644 --- a/sapi/cgi/tests/006.phpt +++ b/sapi/cgi/tests/006.phpt @@ -29,8 +29,12 @@ echo test::$var; file_put_contents($filename, $code); -var_dump(`"$php" -n -l "$filename"`); -var_dump(`"$php" -n -l some.unknown`); +var_dump(shell_exec(<<'); -echo (`$php -n $f`); +echo shell_exec("$php -n $f"); echo "Done\n"; diff --git a/sapi/cgi/tests/010.phpt b/sapi/cgi/tests/010.phpt index 67e1a69e26e..2f5d9a1356d 100644 --- a/sapi/cgi/tests/010.phpt +++ b/sapi/cgi/tests/010.phpt @@ -19,19 +19,19 @@ header("HTTP/1.1 403 Forbidden"); header("Status: 403 Also Forbidden"); ?>'); -echo (`$php -n $f`); +echo shell_exec("$php -n $f"); file_put_contents($f, ''); -echo (`$php -n $f`); +echo shell_exec("$php -n $f"); file_put_contents($f, ''); -echo (`$php -n $f`); +echo shell_exec("$php -n $f"); echo "Done\n"; diff --git a/sapi/cgi/tests/include.inc b/sapi/cgi/tests/include.inc index d155edf4ba2..7d38acca8e8 100644 --- a/sapi/cgi/tests/include.inc +++ b/sapi/cgi/tests/include.inc @@ -9,7 +9,7 @@ function get_cgi_path() /* {{{ */ $cgi = false; if (file_exists($php) && is_executable($php)) { - $version = `$php_escaped -n -v`; + $version = shell_exec("$php_escaped -n -v"); if (strstr($version, "(cli)")) { /* that's cli */ $cli = true; diff --git a/sapi/cli/php_cli_server.c b/sapi/cli/php_cli_server.c index b7e3e5fa1be..92c6ecbdfb5 100644 --- a/sapi/cli/php_cli_server.c +++ b/sapi/cli/php_cli_server.c @@ -2530,6 +2530,7 @@ static void php_cli_server_startup_workers(void) { #if defined(HAVE_PRCTL) || defined(HAVE_PROCCTL) php_cli_server_worker_install_pdeathsig(); #endif + php_child_init(); return; } else { php_cli_server_workers[php_cli_server_worker] = pid; diff --git a/sapi/cli/tests/001.phpt b/sapi/cli/tests/001.phpt index e13ab8def30..bb85ad43435 100644 --- a/sapi/cli/tests/001.phpt +++ b/sapi/cli/tests/001.phpt @@ -7,13 +7,12 @@ version string $php = getenv('TEST_PHP_EXECUTABLE_ESCAPED'); -var_dump(`$php -n -v`); +var_dump(shell_exec("$php -n -v")); echo "Done\n"; ?> --EXPECTF-- string(%d) "PHP %s (cli) (built: %s)%s Copyright (c) The PHP Group -%AZend Engine v%s, Copyright (c) Zend Technologies -" +%AZend Engine v%s, Copyright (c) Zend Technologies%A" Done diff --git a/sapi/cli/tests/002-unix.phpt b/sapi/cli/tests/002-unix.phpt index 40e077bf984..77a8ee0a7c2 100644 --- a/sapi/cli/tests/002-unix.phpt +++ b/sapi/cli/tests/002-unix.phpt @@ -12,7 +12,9 @@ if (substr(PHP_OS, 0, 3) == 'WIN') { $php = getenv('TEST_PHP_EXECUTABLE_ESCAPED'); -var_dump(`$php -n -r 'var_dump("hello");'`); +var_dump(shell_exec(<< diff --git a/sapi/cli/tests/002.phpt b/sapi/cli/tests/002.phpt index 5c6424f5964..81f4f9e3333 100644 --- a/sapi/cli/tests/002.phpt +++ b/sapi/cli/tests/002.phpt @@ -9,7 +9,9 @@ include "skipif.inc"; $php = getenv('TEST_PHP_EXECUTABLE_ESCAPED'); -var_dump(`$php -n -r "var_dump('hello');"`); +var_dump(shell_exec(<< diff --git a/sapi/cli/tests/003-2.phpt b/sapi/cli/tests/003-2.phpt index 88a556b81f5..be1d9d040b5 100644 --- a/sapi/cli/tests/003-2.phpt +++ b/sapi/cli/tests/003-2.phpt @@ -12,8 +12,12 @@ if (substr(PHP_OS, 0, 3) == 'WIN') { $php = getenv('TEST_PHP_EXECUTABLE_ESCAPED'); -var_dump(`$php -nd max_execution_time=111 -r 'var_dump(ini_get("max_execution_time"));'`); -var_dump(`$php -nd max_execution_time=500 -r 'var_dump(ini_get("max_execution_time"));'`); +var_dump(shell_exec(<< --EXPECT-- diff --git a/sapi/cli/tests/003.phpt b/sapi/cli/tests/003.phpt index 20bf61a247b..060d831fe76 100644 --- a/sapi/cli/tests/003.phpt +++ b/sapi/cli/tests/003.phpt @@ -12,10 +12,18 @@ if (substr(PHP_OS, 0, 3) == 'WIN') { $php = getenv('TEST_PHP_EXECUTABLE_ESCAPED'); -var_dump(`$php -n -d max_execution_time=111 -r 'var_dump(ini_get("max_execution_time"));'`); -var_dump(`$php -n -d max_execution_time=500 -r 'var_dump(ini_get("max_execution_time"));'`); -var_dump(`$php -n -d max_execution_time=500 -d max_execution_time=555 -r 'var_dump(ini_get("max_execution_time"));'`); -var_dump(`$php -n -d upload_tmp_dir=/test/path -d max_execution_time=555 -r 'var_dump(ini_get("max_execution_time")); var_dump(ini_get("upload_tmp_dir"));'`); +var_dump(shell_exec(<< diff --git a/sapi/cli/tests/004.phpt b/sapi/cli/tests/004.phpt index 83da934c8ff..c88b85480bd 100644 --- a/sapi/cli/tests/004.phpt +++ b/sapi/cli/tests/004.phpt @@ -9,9 +9,9 @@ include "skipif.inc"; $php = getenv('TEST_PHP_EXECUTABLE_ESCAPED'); -var_dump(`$php -n --rf unknown`); -var_dump(`$php -n --rf echo`); -var_dump(`$php -n --rf phpinfo`); +var_dump(shell_exec("$php -n --rf unknown")); +var_dump(shell_exec("$php -n --rf echo")); +var_dump(shell_exec("$php -n --rf phpinfo")); echo "Done\n"; ?> diff --git a/sapi/cli/tests/005.phpt b/sapi/cli/tests/005.phpt index 0d8ba066cf7..ca168ecfe20 100644 --- a/sapi/cli/tests/005.phpt +++ b/sapi/cli/tests/005.phpt @@ -9,9 +9,9 @@ include "skipif.inc"; $php = getenv('TEST_PHP_EXECUTABLE_ESCAPED'); -var_dump(`$php -n --rc unknown`); -var_dump(`$php -n --rc stdclass`); -var_dump(`$php -n --rc exception`); +var_dump(shell_exec("$php -n --rc unknown")); +var_dump(shell_exec("$php -n --rc stdclass")); +var_dump(shell_exec("$php -n --rc exception")); echo "Done\n"; ?> diff --git a/sapi/cli/tests/006.phpt b/sapi/cli/tests/006.phpt index 38c117ec70f..957543c1a28 100644 --- a/sapi/cli/tests/006.phpt +++ b/sapi/cli/tests/006.phpt @@ -17,9 +17,11 @@ date.timezone=UTC $php = getenv('TEST_PHP_EXECUTABLE_ESCAPED'); -var_dump(`$php -n --re unknown`); -var_dump(`$php -n --re ""`); -var_dump(`$php -n --re pcre`); +var_dump(shell_exec("$php -n --re unknown")); +var_dump(shell_exec(<< diff --git a/sapi/cli/tests/007.phpt b/sapi/cli/tests/007.phpt index 6f27586e27d..afefd2b8ddb 100644 --- a/sapi/cli/tests/007.phpt +++ b/sapi/cli/tests/007.phpt @@ -32,9 +32,15 @@ class test { /* {{{ */ file_put_contents($filename, $code); -var_dump(`$php -n -w "$filename"`); -var_dump(`$php -n -w "wrong"`); -var_dump(`echo "" | $php -n -w`); +var_dump(shell_exec(<<" | $php -n -w +SHELL)); @unlink($filename); diff --git a/sapi/cli/tests/008.phpt b/sapi/cli/tests/008.phpt index a8b20505630..b893473f95f 100644 --- a/sapi/cli/tests/008.phpt +++ b/sapi/cli/tests/008.phpt @@ -26,8 +26,12 @@ var_dump(test::$pri); file_put_contents($filename, $code); -var_dump(`$php -n -f "$filename"`); -var_dump(`$php -n -f "wrong"`); +var_dump(shell_exec(<< diff --git a/sapi/cli/tests/010-2.phpt b/sapi/cli/tests/010-2.phpt index 1fc05f8cfa3..88fe1c832a1 100644 --- a/sapi/cli/tests/010-2.phpt +++ b/sapi/cli/tests/010-2.phpt @@ -22,7 +22,9 @@ hello file_put_contents($filename_txt, $txt); -var_dump(`cat $filename_txt_escaped | $php -n -R "var_dump(1);"`); +var_dump(shell_exec(<< --CLEAN-- diff --git a/sapi/cli/tests/011.phpt b/sapi/cli/tests/011.phpt index d45cb94a08c..ada916d5416 100644 --- a/sapi/cli/tests/011.phpt +++ b/sapi/cli/tests/011.phpt @@ -26,8 +26,8 @@ echo test::$var; file_put_contents($filename, $code); -var_dump(`$php -n -l $filename_escaped`); -var_dump(`$php -n -l some.unknown`); +var_dump(shell_exec("$php -n -l $filename_escaped")); +var_dump(shell_exec("$php -n -l some.unknown")); $code = ' diff --git a/sapi/cli/tests/012.phpt b/sapi/cli/tests/012.phpt index be21b3d99e8..47c086724be 100644 --- a/sapi/cli/tests/012.phpt +++ b/sapi/cli/tests/012.phpt @@ -7,14 +7,14 @@ invalid arguments and error messages $php = getenv('TEST_PHP_EXECUTABLE_ESCAPED'); -var_dump(`$php -n -F some.php -F some.php`); -var_dump(`$php -n -F some.php -R some.php`); -var_dump(`$php -n -R some.php -F some.php`); -var_dump(`$php -n -R some.php -R some.php`); -var_dump(`$php -n -f some.php -f some.php`); -var_dump(`$php -n -B '' -B ''`); -var_dump(`$php -n -E '' -E ''`); -var_dump(`$php -n -r '' -r ''`); +var_dump(shell_exec("$php -n -F some.php -F some.php")); +var_dump(shell_exec("$php -n -F some.php -R some.php")); +var_dump(shell_exec("$php -n -R some.php -F some.php")); +var_dump(shell_exec("$php -n -R some.php -R some.php")); +var_dump(shell_exec("$php -n -f some.php -f some.php")); +var_dump(shell_exec("$php -n -B '' -B ''")); +var_dump(shell_exec("$php -n -E '' -E ''")); +var_dump(shell_exec("$php -n -r '' -r ''")); echo "Done\n"; ?> diff --git a/sapi/cli/tests/013.phpt b/sapi/cli/tests/013.phpt index 345a489403a..42d4f1eb4c3 100644 --- a/sapi/cli/tests/013.phpt +++ b/sapi/cli/tests/013.phpt @@ -16,9 +16,15 @@ $filename_txt = __DIR__."/013.test.txt"; $filename_txt_escaped = escapeshellarg($filename_txt); file_put_contents($filename_txt, "test\nfile\ncontents\n"); -var_dump(`cat $filename_txt_escaped | $php -n -B 'var_dump("start");'`); -var_dump(`cat $filename_txt_escaped | $php -n -E 'var_dump("end");'`); -var_dump(`cat $filename_txt_escaped | $php -n -B 'var_dump("start");' -E 'var_dump("end");'`); +var_dump(shell_exec(<<&1 | grep Usage:`; +echo shell_exec("$php -n --version | grep built:"); +echo shell_exec(<<&1 | grep Usage:"); echo "Done\n"; ?> diff --git a/sapi/cli/tests/016.phpt b/sapi/cli/tests/016.phpt index 544633f592f..0ba9027f216 100644 --- a/sapi/cli/tests/016.phpt +++ b/sapi/cli/tests/016.phpt @@ -56,7 +56,7 @@ EOT; foreach ($codes as $key => $code) { echo "\n--------------\nSnippet no. $key:\n--------------\n"; $code = escapeshellarg($code); - echo `echo $code | $php -a`, "\n"; + echo shell_exec("echo $code | $php -a"), "\n"; } echo "\nDone\n"; diff --git a/sapi/cli/tests/018.phpt b/sapi/cli/tests/018.phpt index 2511fb852e5..ffe92d62059 100644 --- a/sapi/cli/tests/018.phpt +++ b/sapi/cli/tests/018.phpt @@ -13,7 +13,7 @@ if (substr(PHP_OS, 0, 3) == 'WIN') { $php = getenv('TEST_PHP_EXECUTABLE_ESCAPED'); -echo `$php -n -m`; +echo shell_exec("$php -n -m"); echo "Done\n"; ?> diff --git a/sapi/cli/tests/019.phpt b/sapi/cli/tests/019.phpt index 0f5a66c871e..481ea2228b3 100644 --- a/sapi/cli/tests/019.phpt +++ b/sapi/cli/tests/019.phpt @@ -13,7 +13,7 @@ if (substr(PHP_OS, 0, 3) == 'WIN') { $php = getenv('TEST_PHP_EXECUTABLE_ESCAPED'); -echo `$php -n -i`; +echo shell_exec("$php -n -i"); echo "\nDone\n"; ?> diff --git a/sapi/cli/tests/020.phpt b/sapi/cli/tests/020.phpt index 3ccd6a83d3b..4cffe58e75c 100644 --- a/sapi/cli/tests/020.phpt +++ b/sapi/cli/tests/020.phpt @@ -13,8 +13,8 @@ if (substr(PHP_OS, 0, 3) == 'WIN') { $php = getenv('TEST_PHP_EXECUTABLE_ESCAPED'); -echo `$php -n --ri this_extension_does_not_exist_568537753423`; -echo `$php -n --ri standard`; +echo shell_exec("$php -n --ri this_extension_does_not_exist_568537753423"); +echo shell_exec("$php -n --ri standard"); echo "\nDone\n"; ?> diff --git a/sapi/cli/tests/021.phpt b/sapi/cli/tests/021.phpt index 9a24ec454a9..9c25d652eb3 100644 --- a/sapi/cli/tests/021.phpt +++ b/sapi/cli/tests/021.phpt @@ -31,7 +31,7 @@ $script = "#!$php -n\n". file_put_contents($filename, $script); chmod($filename, 0777); -echo `$filename`; +echo shell_exec($filename); echo "\nDone\n"; ?> diff --git a/sapi/cli/tests/025.phpt b/sapi/cli/tests/025.phpt index f0dcb107532..c02467d7baf 100644 --- a/sapi/cli/tests/025.phpt +++ b/sapi/cli/tests/025.phpt @@ -11,7 +11,7 @@ if (substr(PHP_OS, 0, 3) == 'WIN') { ")); ?> diff --git a/sapi/cli/tests/argv_mb.phpt b/sapi/cli/tests/argv_mb.phpt index f7f6dd49081..72df868a04a 100644 --- a/sapi/cli/tests/argv_mb.phpt +++ b/sapi/cli/tests/argv_mb.phpt @@ -13,7 +13,7 @@ $argv_fl = __DIR__ . DIRECTORY_SEPARATOR . "argv_test.php"; $argv_fl_escaped = escapeshellarg($argv_fl); file_put_contents($argv_fl, ""); -var_dump(`$php -n $argv_fl_escaped 多字节字符串 マルチバイト文字列 многобайтоваястрока flerbytesträng`); +var_dump(shell_exec("$php -n $argv_fl_escaped 多字节字符串 マルチバイト文字列 многобайтоваястрока flerbytesträng")); @unlink($argv_fl); diff --git a/sapi/cli/tests/argv_mb_bug77111.phpt b/sapi/cli/tests/argv_mb_bug77111.phpt index b26ef7661b5..e586049a95a 100644 --- a/sapi/cli/tests/argv_mb_bug77111.phpt +++ b/sapi/cli/tests/argv_mb_bug77111.phpt @@ -24,7 +24,7 @@ $out_fl = __DIR__ . "\\argv_bug77111.txt"; $argv_fl = __DIR__ . DIRECTORY_SEPARATOR . "argv_bug77111_test.php"; file_put_contents($argv_fl, ""); -`$php -n $argv_fl Ästhetik Æstetik Esthétique Estética Эстетика`; +shell_exec("$php -n $argv_fl Ästhetik Æstetik Esthétique Estética Эстетика"); var_dump(file_get_contents($out_fl)); ?> diff --git a/sapi/cli/tests/bug71624.phpt b/sapi/cli/tests/bug71624.phpt index 83f48cf921c..d55bf03f139 100644 --- a/sapi/cli/tests/bug71624.phpt +++ b/sapi/cli/tests/bug71624.phpt @@ -22,9 +22,11 @@ file_put_contents($filename_txt, $txt); $test_args = ['$argi', '$argn']; foreach ($test_args as $test_arg) { if (substr(PHP_OS, 0, 3) == 'WIN') { - var_dump(`type $filename_txt_escaped | $php -n -R "echo $test_arg . PHP_EOL;"`); + var_dump(shell_exec(<< --EXPECT-- Interactive shell diff --git a/sapi/fpm/fpm/fpm_conf.c b/sapi/fpm/fpm/fpm_conf.c index e18cfebda08..7743d28f448 100644 --- a/sapi/fpm/fpm/fpm_conf.c +++ b/sapi/fpm/fpm/fpm_conf.c @@ -1383,14 +1383,14 @@ static void fpm_conf_cleanup(int which, void *arg) /* {{{ */ static void fpm_conf_ini_parser_include(char *inc, void *arg) /* {{{ */ { - char *filename; int *error = (int *)arg; php_glob_t g; size_t i; if (!inc || !arg) return; if (*error) return; /* We got already an error. Switch to the end. */ - spprintf(&filename, 0, "%s", ini_filename); + + const char *filename = ini_filename; { g.gl_offs = 0; @@ -1398,31 +1398,26 @@ static void fpm_conf_ini_parser_include(char *inc, void *arg) /* {{{ */ #ifdef PHP_GLOB_NOMATCH if (i == PHP_GLOB_NOMATCH) { zlog(ZLOG_WARNING, "Nothing matches the include pattern '%s' from %s at line %d.", inc, filename, ini_lineno); - efree(filename); return; } #endif /* PHP_GLOB_NOMATCH */ zlog(ZLOG_ERROR, "Unable to globalize '%s' (ret=%zd) from %s at line %d.", inc, i, filename, ini_lineno); *error = 1; - efree(filename); return; } for (i = 0; i < g.gl_pathc; i++) { - int len = strlen(g.gl_pathv[i]); + size_t len = strlen(g.gl_pathv[i]); if (len < 1) continue; if (g.gl_pathv[i][len - 1] == '/') continue; /* don't parse directories */ if (0 > fpm_conf_load_ini_file(g.gl_pathv[i])) { zlog(ZLOG_ERROR, "Unable to include %s from %s at line %d", g.gl_pathv[i], filename, ini_lineno); *error = 1; - efree(filename); return; } } php_globfree(&g); } - - efree(filename); } /* }}} */ diff --git a/sapi/fpm/fpm/fpm_log.c b/sapi/fpm/fpm/fpm_log.c index 6619b7c26f0..87fe4c1d05d 100644 --- a/sapi/fpm/fpm/fpm_log.c +++ b/sapi/fpm/fpm/fpm_log.c @@ -19,11 +19,10 @@ #include "fastcgi.h" #include "zlog.h" -#define FPM_LOG_BUFFER 1024 - static char *fpm_log_format = NULL; static int fpm_log_fd = -1; static struct key_value_s *fpm_access_suppress_paths = NULL; +static struct zlog_stream fpm_log_stream; static int fpm_access_log_suppress(struct fpm_scoreboard_proc_s *proc); @@ -92,7 +91,8 @@ int fpm_log_init_child(struct fpm_worker_pool_s *wp) /* {{{ */ if (fpm_log_fd == -1) { fpm_log_fd = wp->log_fd; } - + zlog_stream_init_ex(&fpm_log_stream, ZLOG_ACCESS_LOG, fpm_log_fd); + zlog_stream_set_wrapping(&fpm_log_stream, 0); for (wp = fpm_worker_all_pools; wp; wp = wp->next) { if (wp->log_fd > -1 && wp->log_fd != fpm_log_fd) { @@ -107,12 +107,11 @@ int fpm_log_init_child(struct fpm_worker_pool_s *wp) /* {{{ */ int fpm_log_write(char *log_format) /* {{{ */ { - char *s, *b; - char buffer[FPM_LOG_BUFFER+1]; - int token, test; - size_t len, len2; + char *s; + bool test, token = false; struct fpm_scoreboard_proc_s proc, *proc_p; struct fpm_scoreboard_s *scoreboard; + struct zlog_stream *stream; char tmp[129]; char format[129]; time_t now_epoch; @@ -126,9 +125,9 @@ int fpm_log_write(char *log_format) /* {{{ */ if (!log_format) { log_format = fpm_log_format; - test = 0; + test = false; } else { - test = 1; + test = true; } now_epoch = time(NULL); @@ -152,38 +151,25 @@ int fpm_log_write(char *log_format) /* {{{ */ } } - token = 0; - - memset(buffer, '\0', sizeof(buffer)); - b = buffer; - len = 0; - s = log_format; + stream = &fpm_log_stream; + zlog_stream_start(stream); while (*s != '\0') { - /* Test is we have place for 1 more char. */ - if (len >= FPM_LOG_BUFFER) { - zlog(ZLOG_NOTICE, "the log buffer is full (%d). The access log request has been truncated.", FPM_LOG_BUFFER); - len = FPM_LOG_BUFFER; - break; - } - if (!token && *s == '%') { - token = 1; + token = true; memset(format, '\0', sizeof(format)); /* reset format */ s++; continue; } if (token) { - token = 0; - len2 = 0; + token = false; switch (*s) { case '%': /* '%' */ - *b = '%'; - len2 = 1; + zlog_stream_char(stream, '%'); break; #ifdef HAVE_TIMES @@ -207,7 +193,7 @@ int fpm_log_write(char *log_format) /* {{{ */ format[0] = '\0'; if (!test) { - len2 = snprintf(b, FPM_LOG_BUFFER - len, "%.2f", tms_total / fpm_scoreboard_get_tick() / (proc.cpu_duration.tv_sec + proc.cpu_duration.tv_usec / 1000000.) * 100.); + zlog_stream_format(stream, "%.2f", tms_total / fpm_scoreboard_get_tick() / (proc.cpu_duration.tv_sec + proc.cpu_duration.tv_usec / 1000000.) * 100.); } break; #endif @@ -216,7 +202,7 @@ int fpm_log_write(char *log_format) /* {{{ */ /* seconds */ if (format[0] == '\0' || !strcasecmp(format, "seconds")) { if (!test) { - len2 = snprintf(b, FPM_LOG_BUFFER - len, "%.3f", proc.duration.tv_sec + proc.duration.tv_usec / 1000000.); + zlog_stream_format(stream, "%.3f", proc.duration.tv_sec + proc.duration.tv_usec / 1000000.); } /* milliseconds */ @@ -225,13 +211,13 @@ int fpm_log_write(char *log_format) /* {{{ */ !strcasecmp(format, "miliseconds") || !strcasecmp(format, "mili") ) { if (!test) { - len2 = snprintf(b, FPM_LOG_BUFFER - len, "%.3f", proc.duration.tv_sec * 1000. + proc.duration.tv_usec / 1000.); + zlog_stream_format(stream, "%.3f", proc.duration.tv_sec * 1000. + proc.duration.tv_usec / 1000.); } /* microseconds */ } else if (!strcasecmp(format, "microseconds") || !strcasecmp(format, "micro")) { if (!test) { - len2 = snprintf(b, FPM_LOG_BUFFER - len, "%lu", (unsigned long)(proc.duration.tv_sec * 1000000UL + proc.duration.tv_usec)); + zlog_stream_format(stream, "%lu", (unsigned long)(proc.duration.tv_sec * 1000000UL + proc.duration.tv_usec)); } } else { @@ -249,26 +235,26 @@ int fpm_log_write(char *log_format) /* {{{ */ if (!test) { char *env = fcgi_getenv((fcgi_request*) SG(server_context), format, strlen(format)); - len2 = snprintf(b, FPM_LOG_BUFFER - len, "%s", env ? env : "-"); + zlog_stream_cstr(stream, env ? env : "-"); } format[0] = '\0'; break; case 'f': /* script */ if (!test) { - len2 = snprintf(b, FPM_LOG_BUFFER - len, "%s", *proc.script_filename ? proc.script_filename : "-"); + zlog_stream_cstr(stream, *proc.script_filename ? proc.script_filename : "-"); } break; case 'l': /* content length */ if (!test) { - len2 = snprintf(b, FPM_LOG_BUFFER - len, "%zu", proc.content_length); + zlog_stream_format(stream, "%zu", proc.content_length); } break; case 'm': /* method */ if (!test) { - len2 = snprintf(b, FPM_LOG_BUFFER - len, "%s", *proc.request_method ? proc.request_method : "-"); + zlog_stream_cstr(stream, *proc.request_method ? proc.request_method : "-"); } break; @@ -276,19 +262,19 @@ int fpm_log_write(char *log_format) /* {{{ */ /* seconds */ if (format[0] == '\0' || !strcasecmp(format, "bytes")) { if (!test) { - len2 = snprintf(b, FPM_LOG_BUFFER - len, "%zu", proc.memory); + zlog_stream_format(stream, "%zu", proc.memory); } /* kilobytes */ } else if (!strcasecmp(format, "kilobytes") || !strcasecmp(format, "kilo")) { if (!test) { - len2 = snprintf(b, FPM_LOG_BUFFER - len, "%zu", proc.memory / 1024); + zlog_stream_format(stream, "%zu", proc.memory / 1024); } /* megabytes */ } else if (!strcasecmp(format, "megabytes") || !strcasecmp(format, "mega")) { if (!test) { - len2 = snprintf(b, FPM_LOG_BUFFER - len, "%zu", proc.memory / 1024 / 1024); + zlog_stream_format(stream, "%zu", proc.memory / 1024 / 1024); } } else { @@ -300,7 +286,7 @@ int fpm_log_write(char *log_format) /* {{{ */ case 'n': /* pool name */ if (!test) { - len2 = snprintf(b, FPM_LOG_BUFFER - len, "%s", scoreboard->pool[0] ? scoreboard->pool : "-"); + zlog_stream_cstr(stream, scoreboard->pool[0] ? scoreboard->pool : "-"); } break; @@ -314,6 +300,7 @@ int fpm_log_write(char *log_format) /* {{{ */ zend_llist_position pos; sapi_headers_struct *sapi_headers = &SG(sapi_headers); size_t format_len = strlen(format); + ssize_t written = 0; h = (sapi_header_struct*)zend_llist_get_first_ex(&sapi_headers->headers, &pos); while (h) { @@ -339,14 +326,13 @@ int fpm_log_write(char *log_format) /* {{{ */ } header = h->header + format_len + 2; - len2 = snprintf(b, FPM_LOG_BUFFER - len, "%s", header && *header ? header : "-"); + written += zlog_stream_cstr(stream, header && *header ? header : "-"); /* found, done */ break; } - if (!len2) { - len2 = 1; - *b = '-'; + if (!written) { + zlog_stream_char(stream, '-'); } } format[0] = '\0'; @@ -354,44 +340,44 @@ int fpm_log_write(char *log_format) /* {{{ */ case 'p': /* PID */ if (!test) { - len2 = snprintf(b, FPM_LOG_BUFFER - len, "%ld", (long)getpid()); + zlog_stream_format(stream, "%ld", (long)getpid()); } break; case 'P': /* PID */ if (!test) { - len2 = snprintf(b, FPM_LOG_BUFFER - len, "%ld", (long)getppid()); + zlog_stream_format(stream, "%ld", (long)getppid()); } break; case 'q': /* query_string */ if (!test) { - len2 = snprintf(b, FPM_LOG_BUFFER - len, "%s", proc.query_string); + zlog_stream_cstr(stream, proc.query_string); } break; case 'Q': /* '?' */ if (!test) { - len2 = snprintf(b, FPM_LOG_BUFFER - len, "%s", *proc.query_string ? "?" : ""); + zlog_stream_cstr(stream, *proc.query_string ? "?" : ""); } break; case 'r': /* request URI */ if (!test) { - len2 = snprintf(b, FPM_LOG_BUFFER - len, "%s", proc.request_uri); + zlog_stream_cstr(stream, proc.request_uri); } break; case 'R': /* remote IP address */ if (!test) { const char *tmp = fcgi_get_last_client_ip(); - len2 = snprintf(b, FPM_LOG_BUFFER - len, "%s", tmp ? tmp : "-"); + zlog_stream_cstr(stream, tmp ? tmp : "-"); } break; case 's': /* status */ if (!test) { - len2 = snprintf(b, FPM_LOG_BUFFER - len, "%d", SG(sapi_headers).http_response_code); + zlog_stream_format(stream, "%d", SG(sapi_headers).http_response_code); } break; @@ -409,14 +395,14 @@ int fpm_log_write(char *log_format) /* {{{ */ } else { strftime(tmp, sizeof(tmp) - 1, format, localtime(t)); } - len2 = snprintf(b, FPM_LOG_BUFFER - len, "%s", tmp); + zlog_stream_cstr(stream, tmp); } format[0] = '\0'; break; case 'u': /* remote user */ if (!test) { - len2 = snprintf(b, FPM_LOG_BUFFER - len, "%s", proc.auth_user); + zlog_stream_cstr(stream, proc.auth_user); } break; @@ -459,30 +445,28 @@ int fpm_log_write(char *log_format) /* {{{ */ return -1; } s++; - if (!test) { - b += len2; - len += len2; - } - if (len >= FPM_LOG_BUFFER) { - zlog(ZLOG_NOTICE, "the log buffer is full (%d). The access log request has been truncated.", FPM_LOG_BUFFER); - len = FPM_LOG_BUFFER; + + if (zlog_stream_is_over_limit(stream)) { + zlog(ZLOG_NOTICE, "the log buffer is over the configured limit. The access log request has been truncated."); break; } continue; } + if (zlog_stream_is_over_limit(stream)) { + zlog(ZLOG_NOTICE, "the log buffer is over the configured limit. The access log request has been truncated."); + break; + } + if (!test) { // push the normal char to the output buffer - *b = *s; - b++; - len++; + zlog_stream_char(stream, *s); } s++; } - if (!test && strlen(buffer) > 0) { - buffer[len] = '\n'; - zend_quiet_write(fpm_log_fd, buffer, len + 1); + if (!test) { + zlog_stream_finish(stream); } return 0; diff --git a/sapi/fpm/fpm/fpm_php.c b/sapi/fpm/fpm/fpm_php.c index fb02a3e1917..55b0377c1ad 100644 --- a/sapi/fpm/fpm/fpm_php.c +++ b/sapi/fpm/fpm/fpm_php.c @@ -253,6 +253,9 @@ int fpm_php_init_child(struct fpm_worker_pool_s *wp) /* {{{ */ limit_extensions = wp->limit_extensions; wp->limit_extensions = NULL; } + + php_child_init(); + return 0; } /* }}} */ diff --git a/sapi/fpm/fpm/fpm_scoreboard.h b/sapi/fpm/fpm/fpm_scoreboard.h index 5f298a41ae6..65d243ae53f 100644 --- a/sapi/fpm/fpm/fpm_scoreboard.h +++ b/sapi/fpm/fpm/fpm_scoreboard.h @@ -34,11 +34,11 @@ struct fpm_scoreboard_proc_s { struct timeval duration; time_t accepted_epoch; struct timeval tv; - char request_uri[128]; - char query_string[512]; + char request_uri[512]; + char query_string[2048]; char request_method[16]; size_t content_length; /* used with POST only */ - char script_filename[256]; + char script_filename[512]; char auth_user[32]; #ifdef HAVE_TIMES struct tms cpu_accepted; diff --git a/sapi/fpm/fpm/zlog.c b/sapi/fpm/fpm/zlog.c index 39c6eec885b..803a768234b 100644 --- a/sapi/fpm/fpm/zlog.c +++ b/sapi/fpm/fpm/zlog.c @@ -410,8 +410,16 @@ static inline ssize_t zlog_stream_unbuffered_write( } /* }}} */ -static inline ssize_t zlog_stream_buf_copy_cstr( - struct zlog_stream *stream, const char *str, size_t str_len) /* {{{ */ +void zlog_stream_start(struct zlog_stream *stream) +{ + stream->finished = 0; + stream->len = 0; + stream->full = 0; + stream->over_limit = 0; +} + +static ssize_t zlog_stream_buf_copy_cstr( + struct zlog_stream *stream, const char *str, size_t str_len) { ZEND_ASSERT(stream->len <= stream->buf.size); if (stream->buf.size - stream->len <= str_len && @@ -419,25 +427,32 @@ static inline ssize_t zlog_stream_buf_copy_cstr( return -1; } + if (stream->buf.size - stream->len <= str_len) { + stream->over_limit = 1; + str_len = stream->buf.size - stream->len; + } memcpy(stream->buf.data + stream->len, str, str_len); stream->len += str_len; return str_len; } -/* }}} */ -static inline ssize_t zlog_stream_buf_copy_char(struct zlog_stream *stream, char c) /* {{{ */ +static ssize_t zlog_stream_buf_copy_char(struct zlog_stream *stream, char c) { ZEND_ASSERT(stream->len <= stream->buf.size); - if (stream->buf.size - stream->len < 1 && !zlog_stream_buf_alloc_ex(stream, 1)) { + if (stream->buf.size == stream->len && !zlog_stream_buf_alloc_ex(stream, 1)) { return -1; } + if (stream->buf.size == stream->len) { + stream->over_limit = 1; + return 0; + } + stream->buf.data[stream->len++] = c; return 1; } -/* }}} */ static ssize_t zlog_stream_buf_flush(struct zlog_stream *stream) /* {{{ */ { @@ -466,8 +481,8 @@ static ssize_t zlog_stream_buf_flush(struct zlog_stream *stream) /* {{{ */ static ssize_t zlog_stream_buf_append( struct zlog_stream *stream, const char *str, size_t str_len) /* {{{ */ { - int over_limit = 0; size_t available_len, required_len, reserved_len; + int over_limit = 0; if (stream->len == 0) { stream->len = zlog_stream_prefix_ex(stream, stream->function, stream->line); @@ -477,7 +492,7 @@ static ssize_t zlog_stream_buf_append( reserved_len = stream->len + stream->msg_suffix_len + stream->msg_quote; required_len = reserved_len + str_len; if (required_len >= zlog_limit) { - over_limit = 1; + stream->over_limit = over_limit = 1; available_len = zlog_limit - reserved_len - 1; } else { available_len = str_len; @@ -521,16 +536,21 @@ static inline void zlog_stream_init_internal( stream->flags = flags; stream->use_syslog = fd == ZLOG_SYSLOG; stream->use_fd = fd > 0; - stream->use_buffer = zlog_buffering || external_logger != NULL || stream->use_syslog; - stream->buf_init_size = capacity; - stream->use_stderr = fd < 0 || - ( - fd != STDERR_FILENO && fd != STDOUT_FILENO && !launched && - (flags & ZLOG_LEVEL_MASK) >= ZLOG_NOTICE - ); - stream->prefix_buffer = (flags & ZLOG_LEVEL_MASK) >= zlog_level && - (stream->use_fd || stream->use_stderr || stream->use_syslog); stream->fd = fd > -1 ? fd : STDERR_FILENO; + stream->buf_init_size = capacity; + if (flags & ZLOG_ACCESS_LOG) { + stream->use_buffer = 1; + stream->use_stderr = fd < 0; + } else { + stream->use_buffer = zlog_buffering || external_logger != NULL || stream->use_syslog; + stream->use_stderr = fd < 0 || + ( + fd != STDERR_FILENO && fd != STDOUT_FILENO && !launched && + (flags & ZLOG_LEVEL_MASK) >= ZLOG_NOTICE + ); + stream->prefix_buffer = (flags & ZLOG_LEVEL_MASK) >= zlog_level && + (stream->use_fd || stream->use_stderr || stream->use_syslog); + } } /* }}} */ @@ -745,7 +765,7 @@ ssize_t zlog_stream_format(struct zlog_stream *stream, const char *fmt, ...) /* } /* }}} */ -ssize_t zlog_stream_str(struct zlog_stream *stream, const char *str, size_t str_len) /* {{{ */ +ssize_t zlog_stream_str(struct zlog_stream *stream, const char *str, size_t str_len) { /* do not write anything if the stream is full or str is empty */ if (str_len == 0 || stream->full) { @@ -754,9 +774,7 @@ ssize_t zlog_stream_str(struct zlog_stream *stream, const char *str, size_t str_ /* reset stream if it is finished */ if (stream->finished) { - stream->finished = 0; - stream->len = 0; - stream->full = 0; + zlog_stream_start(stream); } if (stream->use_buffer) { @@ -765,7 +783,25 @@ ssize_t zlog_stream_str(struct zlog_stream *stream, const char *str, size_t str_ return zlog_stream_unbuffered_write(stream, str, str_len); } -/* }}} */ + +ssize_t zlog_stream_char(struct zlog_stream *stream, char c) +{ + /* do not write anything if the stream is full */ + if (stream->full) { + return 0; + } + + /* reset stream if it is finished */ + if (stream->finished) { + zlog_stream_start(stream); + } + + if (stream->use_buffer) { + return zlog_stream_buf_copy_char(stream, c); + } + const char tmp[1] = {c}; + return zlog_stream_direct_write(stream, tmp, 1); +} static inline void zlog_stream_finish_buffer_suffix(struct zlog_stream *stream) /* {{{ */ { @@ -883,3 +919,8 @@ zlog_bool zlog_stream_close(struct zlog_stream *stream) /* {{{ */ return finished; } /* }}} */ + +zlog_bool zlog_stream_is_over_limit(struct zlog_stream *stream) +{ + return stream->over_limit; +} diff --git a/sapi/fpm/fpm/zlog.h b/sapi/fpm/fpm/zlog.h index be22acc32f3..6886a0ae807 100644 --- a/sapi/fpm/fpm/zlog.h +++ b/sapi/fpm/fpm/zlog.h @@ -48,6 +48,8 @@ enum { #define ZLOG_LEVEL_MASK 7 +#define ZLOG_ACCESS_LOG 16 + #define ZLOG_HAVE_ERRNO 0x100 #define ZLOG_SYSERROR (ZLOG_ERROR | ZLOG_HAVE_ERRNO) @@ -74,6 +76,7 @@ struct zlog_stream { unsigned int msg_quote:1; unsigned int decorate:1; unsigned int is_stdout:1; + unsigned int over_limit:1; int fd; int line; int child_pid; @@ -103,14 +106,22 @@ zlog_bool zlog_stream_set_msg_suffix( struct zlog_stream *stream, const char *suffix, const char *final_suffix); #define zlog_stream_prefix(stream) \ zlog_stream_prefix_ex(stream, __func__, __LINE__) +void zlog_stream_start(struct zlog_stream *stream); ssize_t zlog_stream_prefix_ex(struct zlog_stream *stream, const char *function, int line); ssize_t zlog_stream_format(struct zlog_stream *stream, const char *fmt, ...) __attribute__ ((format(printf,2,3))); ssize_t zlog_stream_vformat(struct zlog_stream *stream, const char *fmt, va_list args); ssize_t zlog_stream_str(struct zlog_stream *stream, const char *str, size_t str_len); +ssize_t zlog_stream_char(struct zlog_stream *stream, char c); zlog_bool zlog_stream_finish(struct zlog_stream *stream); void zlog_stream_destroy(struct zlog_stream *stream); zlog_bool zlog_stream_close(struct zlog_stream *stream); +zlog_bool zlog_stream_is_over_limit(struct zlog_stream *stream); + +static inline ssize_t zlog_stream_cstr(struct zlog_stream *stream, const char *cstr) +{ + return zlog_stream_str(stream, cstr, strlen(cstr)); +} /* default log limit */ #define ZLOG_DEFAULT_LIMIT 1024 diff --git a/sapi/fpm/tests/log-access-extended-limit.phpt b/sapi/fpm/tests/log-access-extended-limit.phpt new file mode 100644 index 00000000000..99c17f14905 --- /dev/null +++ b/sapi/fpm/tests/log-access-extended-limit.phpt @@ -0,0 +1,56 @@ +--TEST-- +FPM: Test extended access log limit +--SKIPIF-- + +--FILE-- +start(['--prefix', $prefix]); +$tester->expectLogStartNotices(); +$tester->request(query: 'a=' . str_repeat('a', 1500))->expectBody('OK'); +$tester->expectAccessLog("'GET /log-access-extended-limit.src.php?a=" . str_repeat('a', 1500) . "' 200"); +$tester->request(query: 'a=' . str_repeat('a', 2040))->expectBody('OK'); +$tester->expectAccessLog("'GET /log-access-extended-limit.src.php?a=" . str_repeat('a', 2002) . '...'); +$tester->terminate(); +$tester->expectLogTerminatingNotices(); +$tester->close(); +$tester->checkAccessLog(); + +?> +Done +--EXPECT-- +Done +--CLEAN-- + diff --git a/sapi/fpm/tests/main-version.phpt b/sapi/fpm/tests/main-version.phpt index 5ae83562d07..8c7dbe78c92 100644 --- a/sapi/fpm/tests/main-version.phpt +++ b/sapi/fpm/tests/main-version.phpt @@ -9,13 +9,12 @@ require_once "tester.inc"; $php = \FPM\Tester::findExecutable(); -var_dump(`$php -n -v`); +var_dump(shell_exec("$php -n -v")); echo "Done\n"; ?> --EXPECTF-- string(%d) "PHP %s (fpm%s (built: %s Copyright (c) The PHP Group -%AZend Engine v%s, Copyright (c) Zend Technologies -" +%AZend Engine v%s, Copyright (c) Zend Technologies%A" Done diff --git a/sapi/fuzzer/README.md b/sapi/fuzzer/README.md index b4bb2bbe457..42e1eb7fa30 100644 --- a/sapi/fuzzer/README.md +++ b/sapi/fuzzer/README.md @@ -31,8 +31,8 @@ When running `make` it creates these binaries in `sapi/fuzzer/`: * `php-fuzz-mbstring`: Fuzzing `mb_convert_encoding()` (requires `--enable-mbstring`) * `php-fuzz-mbregex`: Fuzzing `mb_ereg[i]()` (requires --enable-mbstring) * `php-fuzz-execute`: Fuzzing the executor -* `php-fuzz-function-jit`: Fuzzing the function JIT (requires --enable-opcache) -* `php-fuzz-tracing-jit`: Fuzzing the tracing JIT (requires --enable-opcache) +* `php-fuzz-function-jit`: Fuzzing the function JIT +* `php-fuzz-tracing-jit`: Fuzzing the tracing JIT Some fuzzers have a seed corpus in `sapi/fuzzer/corpus`. You can use it as follows: diff --git a/sapi/fuzzer/fuzzer-execute-common.h b/sapi/fuzzer/fuzzer-execute-common.h index 081ab4d30e8..20fcad111cd 100644 --- a/sapi/fuzzer/fuzzer-execute-common.h +++ b/sapi/fuzzer/fuzzer-execute-common.h @@ -53,7 +53,18 @@ static zend_always_inline void fuzzer_step(void) { static void (*orig_execute_ex)(zend_execute_data *execute_data); static void fuzzer_execute_ex(zend_execute_data *execute_data) { + +#ifdef ZEND_CHECK_STACK_LIMIT + if (UNEXPECTED(zend_call_stack_overflowed(EG(stack_limit)))) { + zend_call_stack_size_error(); + /* No opline was executed before exception */ + EG(opline_before_exception) = NULL; + /* Fall through to handle exception below. */ + } +#endif /* ZEND_CHECK_STACK_LIMIT */ + const zend_op *opline = EX(opline); + while (1) { fuzzer_step(); opline = ((opcode_handler_t) opline->handler)(execute_data, opline); @@ -139,33 +150,3 @@ ZEND_ATTRIBUTE_UNUSED static void opcache_invalidate(void) { zval_ptr_dtor(&retval); zend_exception_restore(); } - -ZEND_ATTRIBUTE_UNUSED char *get_opcache_path(void) { - /* Try relative to cwd. */ - char *p = realpath("modules/opcache.so", NULL); - if (p) { - return p; - } - - /* 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; - } - - /* Get basename. */ - char *last_sep = strrchr(path, '/'); - if (last_sep) { - *last_sep = '\0'; - } - - strlcat(path, "/modules/opcache.so", sizeof(path)); - return realpath(path, NULL); -} diff --git a/sapi/fuzzer/fuzzer-function-jit.c b/sapi/fuzzer/fuzzer-function-jit.c index 92415c2a0e1..d2117f0027c 100644 --- a/sapi/fuzzer/fuzzer-function-jit.c +++ b/sapi/fuzzer/fuzzer-function-jit.c @@ -50,18 +50,12 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { } int LLVMFuzzerInitialize(int *argc, char ***argv) { - char *opcache_path = get_opcache_path(); - assert(opcache_path && "Failed to determine opcache path"); - char ini_buf[512]; snprintf(ini_buf, sizeof(ini_buf), - "zend_extension=%s\n" "opcache.validate_timestamps=0\n" "opcache.file_update_protection=0\n" "opcache.jit_buffer_size=128M\n" - "opcache.protect_memory=1\n", - opcache_path); - free(opcache_path); + "opcache.protect_memory=1\n"); create_file(); fuzzer_init_php_for_execute(ini_buf); diff --git a/sapi/fuzzer/fuzzer-sapi.c b/sapi/fuzzer/fuzzer-sapi.c index 5014a51cca4..3cffacae1d1 100644 --- a/sapi/fuzzer/fuzzer-sapi.c +++ b/sapi/fuzzer/fuzzer-sapi.c @@ -45,7 +45,7 @@ static const char HARDCODED_INI[] = "allow_url_include=0\n" "allow_url_fopen=0\n" "open_basedir=/tmp\n" - "disable_functions=dl,mail,mb_send_mail" + "disable_functions=dl,mail,mb_send_mail,set_error_handler" ",shell_exec,exec,system,proc_open,popen,passthru,pcntl_exec" ",chdir,chgrp,chmod,chown,copy,file_put_contents,lchgrp,lchown,link,mkdir" ",move_uploaded_file,rename,rmdir,symlink,tempname,touch,unlink,fopen" diff --git a/sapi/fuzzer/fuzzer-tracing-jit.c b/sapi/fuzzer/fuzzer-tracing-jit.c index 437938d0902..65d661f139c 100644 --- a/sapi/fuzzer/fuzzer-tracing-jit.c +++ b/sapi/fuzzer/fuzzer-tracing-jit.c @@ -54,12 +54,8 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { } int LLVMFuzzerInitialize(int *argc, char ***argv) { - char *opcache_path = get_opcache_path(); - assert(opcache_path && "Failed to determine opcache path"); - char ini_buf[512]; snprintf(ini_buf, sizeof(ini_buf), - "zend_extension=%s\n" "opcache.validate_timestamps=0\n" "opcache.file_update_protection=0\n" "opcache.memory_consumption=1024\n" @@ -71,9 +67,7 @@ int LLVMFuzzerInitialize(int *argc, char ***argv) { "opcache.jit_max_root_traces=100000\n" "opcache.jit_max_side_traces=100000\n" "opcache.jit_max_exit_counters=100000\n" - "opcache.protect_memory=1\n", - opcache_path); - free(opcache_path); + "opcache.protect_memory=1\n"); create_file(); fuzzer_init_php_for_execute(ini_buf); diff --git a/sapi/litespeed/lsapi_main.c b/sapi/litespeed/lsapi_main.c index 432c0338c46..d095f9ae90e 100644 --- a/sapi/litespeed/lsapi_main.c +++ b/sapi/litespeed/lsapi_main.c @@ -1395,6 +1395,8 @@ void start_children( int children ) switch( pid ) { case 0: /* children process */ + php_child_init(); + /* don't catch our signals */ sigaction( SIGTERM, &old_term, 0 ); sigaction( SIGQUIT, &old_quit, 0 ); diff --git a/sapi/litespeed/lscriu.c b/sapi/litespeed/lscriu.c index 09ad53e233c..042f5fb7a2b 100644 --- a/sapi/litespeed/lscriu.c +++ b/sapi/litespeed/lscriu.c @@ -85,6 +85,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "lscriu.h" #include +#include "main/php_main.h" #define LSCRIU_PATH 256 @@ -459,6 +460,7 @@ static void LSCRIU_CloudLinux_Checkpoint(void) else { s_restored = 1; LSAPI_reset_server_state(); + php_child_init(); /* Here we have restored the php process, so we should to tell (via semaphore) mod_lsapi that we are started and ready to receive data. @@ -532,6 +534,7 @@ static void LSCRIU_try_checkpoint(int *forked_pid) LSCRIU_Wait_Dump_Finish_Or_Restored(iPidParent); LSCRIU_Restored_Error(0, "Restored!"); LSAPI_reset_server_state(); + php_child_init(); s_restored = 1; } else { diff --git a/sapi/phpdbg/phpdbg_prompt.c b/sapi/phpdbg/phpdbg_prompt.c index 84bd7a076ac..e797a696a4b 100644 --- a/sapi/phpdbg/phpdbg_prompt.c +++ b/sapi/phpdbg/phpdbg_prompt.c @@ -111,7 +111,7 @@ static inline int phpdbg_call_register(phpdbg_param_t *stack) /* {{{ */ array_init(¶ms); while (next) { - char *buffered = NULL; + zend_string *buffered = NULL; switch (next->type) { case OP_PARAM: @@ -125,28 +125,28 @@ static inline int phpdbg_call_register(phpdbg_param_t *stack) /* {{{ */ break; case METHOD_PARAM: - spprintf(&buffered, 0, "%s::%s", next->method.class, next->method.name); - add_next_index_string(¶ms, buffered); + buffered = strpprintf(0, "%s::%s", next->method.class, next->method.name); + add_next_index_str(¶ms, buffered); break; case NUMERIC_METHOD_PARAM: - spprintf(&buffered, 0, "%s::%s#"ZEND_LONG_FMT, next->method.class, next->method.name, next->num); - add_next_index_string(¶ms, buffered); + buffered = strpprintf(0, "%s::%s#"ZEND_LONG_FMT, next->method.class, next->method.name, next->num); + add_next_index_str(¶ms, buffered); break; case NUMERIC_FUNCTION_PARAM: - spprintf(&buffered, 0, "%s#"ZEND_LONG_FMT, next->str, next->num); - add_next_index_string(¶ms, buffered); + buffered = strpprintf(0, "%s#"ZEND_LONG_FMT, next->str, next->num); + add_next_index_str(¶ms, buffered); break; case FILE_PARAM: - spprintf(&buffered, 0, "%s:"ZEND_ULONG_FMT, next->file.name, next->file.line); - add_next_index_string(¶ms, buffered); + buffered = strpprintf(0, "%s:"ZEND_ULONG_FMT, next->file.name, next->file.line); + add_next_index_str(¶ms, buffered); break; case NUMERIC_FILE_PARAM: - spprintf(&buffered, 0, "%s:#"ZEND_ULONG_FMT, next->file.name, next->file.line); - add_next_index_string(¶ms, buffered); + buffered = strpprintf(0, "%s:#"ZEND_ULONG_FMT, next->file.name, next->file.line); + add_next_index_str(¶ms, buffered); break; default: { diff --git a/sapi/phpdbg/phpdbg_watch.c b/sapi/phpdbg/phpdbg_watch.c index 4478dca0516..5657649efdb 100644 --- a/sapi/phpdbg/phpdbg_watch.c +++ b/sapi/phpdbg/phpdbg_watch.c @@ -139,7 +139,7 @@ bool phpdbg_check_watch_diff(phpdbg_watchtype type, void *oldPtr, void *newPtr) switch (type) { case WATCH_ON_BUCKET: if (memcmp(&((Bucket *) oldPtr)->h, &((Bucket *) newPtr)->h, sizeof(Bucket) - sizeof(zval) /* hash+key comparison */) != 0) { - return 2; + return true; } /* Fall through to also compare the value from the bucket. */ ZEND_FALLTHROUGH; @@ -154,7 +154,7 @@ bool phpdbg_check_watch_diff(phpdbg_watchtype type, void *oldPtr, void *newPtr) case WATCH_ON_HASHDATA: ZEND_UNREACHABLE(); } - return 0; + return false; } void phpdbg_print_watch_diff(phpdbg_watchtype type, zend_string *name, void *oldPtr, void *newPtr) { @@ -280,9 +280,9 @@ static inline void phpdbg_deactivate_watchpoint(phpdbg_watchpoint_t *watch) { /* Note that consecutive pages need to be merged in order to avoid watchpoints spanning page boundaries to have part of their data in the one page, part in the other page */ #ifdef _WIN32 -int phpdbg_watchpoint_segfault_handler(void *addr) { +zend_result phpdbg_watchpoint_segfault_handler(void *addr) { #else -int phpdbg_watchpoint_segfault_handler(siginfo_t *info, void *context) { +zend_result phpdbg_watchpoint_segfault_handler(siginfo_t *info, void *context) { #endif void *page = phpdbg_get_page_boundary( @@ -562,12 +562,12 @@ bool phpdbg_is_recursively_watched(void *ptr, phpdbg_watch_element *element) { do { element = next; if (element->watch->addr.ptr == ptr) { - return 1; + return true; } next = element->parent; } while (!(element->flags & PHPDBG_WATCH_RECURSIVE_ROOT)); - return 0; + return false; } void phpdbg_add_recursive_watch_from_ht(phpdbg_watch_element *element, zend_long idx, zend_string *str, zval *zv) { @@ -721,7 +721,7 @@ bool phpdbg_try_re_adding_watch_element(zval *parent, phpdbg_watch_element *elem HashTable *ht = HT_FROM_ZVP(parent); if (!ht) { - return 0; + return false; } else if (element->flags & (PHPDBG_WATCH_ARRAY | PHPDBG_WATCH_OBJECT)) { char *htPtr = ((char *) ht) + HT_WATCH_OFFSET; char *oldPtr = ((char *) &element->backup.ht) + HT_WATCH_OFFSET; @@ -742,7 +742,7 @@ bool phpdbg_try_re_adding_watch_element(zval *parent, phpdbg_watch_element *elem } if (!phpdbg_try_re_adding_watch_element(next, element->child)) { - return 0; + return false; } } else if (phpdbg_check_watch_diff(WATCH_ON_ZVAL, &element->backup.zv, zv)) { phpdbg_print_watch_diff(WATCH_ON_ZVAL, element->str, &element->backup.zv, zv); @@ -752,10 +752,10 @@ bool phpdbg_try_re_adding_watch_element(zval *parent, phpdbg_watch_element *elem phpdbg_add_bucket_watch_element((Bucket *) zv, element); phpdbg_watch_parent_ht(element); } else { - return 0; + return false; } - return 1; + return true; } void phpdbg_automatic_dequeue_free(phpdbg_watch_element *element) { @@ -1481,7 +1481,7 @@ void phpdbg_setup_watchpoints(void) { #ifdef HAVE_USERFAULTFD_WRITEFAULT int flags = O_CLOEXEC; #ifdef UFFD_USER_MODE_ONLY - // unpriviliged userfaultfd are disabled by default, + // unprivileged userfaultfd are disabled by default, // with this flag it allows ranges from the user space // being reported. flags |= UFFD_USER_MODE_ONLY; diff --git a/sapi/phpdbg/phpdbg_watch.h b/sapi/phpdbg/phpdbg_watch.h index 17d9dfac93d..56f4b29379c 100644 --- a/sapi/phpdbg/phpdbg_watch.h +++ b/sapi/phpdbg/phpdbg_watch.h @@ -115,9 +115,9 @@ void phpdbg_destroy_watchpoints(void); void phpdbg_purge_watchpoint_tree(void); #ifndef _WIN32 -int phpdbg_watchpoint_segfault_handler(siginfo_t *info, void *context); +zend_result phpdbg_watchpoint_segfault_handler(siginfo_t *info, void *context); #else -int phpdbg_watchpoint_segfault_handler(void *addr); +zend_result phpdbg_watchpoint_segfault_handler(void *addr); #endif void phpdbg_create_addr_watchpoint(void *addr, size_t size, phpdbg_watchpoint_t *watch); diff --git a/sapi/phpdbg/tests/bug73615.phpt b/sapi/phpdbg/tests/bug73615.phpt index 2208cdebf70..843424d7b36 100644 --- a/sapi/phpdbg/tests/bug73615.phpt +++ b/sapi/phpdbg/tests/bug73615.phpt @@ -11,7 +11,7 @@ $phpdbg = getenv('TEST_PHPDBG_EXECUTABLE_ESCAPED'); chdir(__DIR__."/bug73615"); -print `$phpdbg -qn`; +print shell_exec("$phpdbg -qn"); ?> --EXPECT-- diff --git a/scripts/dev/bless_tests.php b/scripts/dev/bless_tests.php index 03927cfd005..58baeac4024 100755 --- a/scripts/dev/bless_tests.php +++ b/scripts/dev/bless_tests.php @@ -65,7 +65,7 @@ function normalizeOutput(string $out): string { $out = preg_replace('/in (\/|[A-Z]:\\\\)\S+ on line \d+/m', 'in %s on line %d', $out); $out = preg_replace('/in (\/|[A-Z]:\\\\)\S+:\d+/m', 'in %s:%d', $out); $out = preg_replace('/\{closure:(\/|[A-Z]:\\\\)\S+:\d+\}/', '{closure:%s:%d}', $out); - $out = preg_replace('/object\(([A-Za-z0-9]*)\)#\d+/', 'object($1)#%d', $out); + $out = preg_replace('/object\(([A-Za-z0-9\\\\]*)\)#\d+/', 'object($1)#%d', $out); $out = preg_replace('/^#(\d+) (\/|[A-Z]:\\\\)\S+\(\d+\):/m', '#$1 %s(%d):', $out); $out = preg_replace('/Resource id #\d+/', 'Resource id #%d', $out); $out = preg_replace('/resource\(\d+\) of type/', 'resource(%d) of type', $out); diff --git a/tests/basic/bug31875.phpt b/tests/basic/bug31875.phpt index 0fdc134d637..ee9b466fa7d 100644 --- a/tests/basic/bug31875.phpt +++ b/tests/basic/bug31875.phpt @@ -22,6 +22,8 @@ var_dump(in_array($disabled_function, $functions['internal'])); --EXPECTF-- bool(false) -Deprecated: get_defined_functions(): Setting $exclude_disabled to false has no effect in %s on line %d +Deprecated: get_defined_functions(): The $exclude_disabled parameter has no effect since PHP 8.0 in %s on line %d bool(false) + +Deprecated: get_defined_functions(): The $exclude_disabled parameter has no effect since PHP 8.0 in %s on line %d bool(false) diff --git a/tests/basic/gh17951_ini_parse_1.phpt b/tests/basic/gh17951_ini_parse_1.phpt new file mode 100644 index 00000000000..fe0dea138e4 --- /dev/null +++ b/tests/basic/gh17951_ini_parse_1.phpt @@ -0,0 +1,15 @@ +--TEST-- +GH-17951 INI Parse 1 +--CREDITS-- +Frederik Milling Pytlick (frederikpyt@protonmail.com) +--INI-- +memory_limit=128M +max_memory_limit=-1 +--FILE-- + +--EXPECT-- +-1 +128M diff --git a/tests/basic/gh17951_ini_parse_2.phpt b/tests/basic/gh17951_ini_parse_2.phpt new file mode 100644 index 00000000000..e0f290f4c2c --- /dev/null +++ b/tests/basic/gh17951_ini_parse_2.phpt @@ -0,0 +1,15 @@ +--TEST-- +GH-17951 INI Parse 2 +--CREDITS-- +Frederik Milling Pytlick (frederikpyt@protonmail.com) +--INI-- +memory_limit=-1 +max_memory_limit=-1 +--FILE-- + +--EXPECT-- +-1 +-1 diff --git a/tests/basic/gh17951_ini_parse_3.phpt b/tests/basic/gh17951_ini_parse_3.phpt new file mode 100644 index 00000000000..50576714186 --- /dev/null +++ b/tests/basic/gh17951_ini_parse_3.phpt @@ -0,0 +1,15 @@ +--TEST-- +GH-17951 INI Parse 3 +--CREDITS-- +Frederik Milling Pytlick (frederikpyt@protonmail.com) +--INI-- +memory_limit=128M +max_memory_limit=256M +--FILE-- + +--EXPECT-- +256M +128M diff --git a/tests/basic/gh17951_ini_parse_4.phpt b/tests/basic/gh17951_ini_parse_4.phpt new file mode 100644 index 00000000000..5690a133d77 --- /dev/null +++ b/tests/basic/gh17951_ini_parse_4.phpt @@ -0,0 +1,15 @@ +--TEST-- +GH-17951 INI Parse 4 +--CREDITS-- +Frederik Milling Pytlick (frederikpyt@protonmail.com) +--INI-- +memory_limit=-1 +max_memory_limit=128M +--FILE-- + +--EXPECT-- +128M +128M diff --git a/tests/basic/gh17951_ini_parse_5.phpt b/tests/basic/gh17951_ini_parse_5.phpt new file mode 100644 index 00000000000..20e41452600 --- /dev/null +++ b/tests/basic/gh17951_ini_parse_5.phpt @@ -0,0 +1,16 @@ +--TEST-- +GH-17951 INI Parse 5 +--CREDITS-- +Frederik Milling Pytlick (frederikpyt@protonmail.com) +--INI-- +memory_limit=256M +max_memory_limit=128M +--FILE-- + +--EXPECT-- +Warning: Failed to set memory_limit to 268435456 bytes. Setting to max_memory_limit instead (currently: 134217728 bytes) in Unknown on line 0 +128M +128M diff --git a/tests/basic/gh17951_runtime_change_1.phpt b/tests/basic/gh17951_runtime_change_1.phpt new file mode 100644 index 00000000000..12b7b746f2b --- /dev/null +++ b/tests/basic/gh17951_runtime_change_1.phpt @@ -0,0 +1,14 @@ +--TEST-- +GH-17951 Runtime Change 1 +--CREDITS-- +Frederik Milling Pytlick (frederikpyt@protonmail.com) +--INI-- +memory_limit=128M +max_memory_limit=512M +--FILE-- + +--EXPECT-- +256M diff --git a/tests/basic/gh17951_runtime_change_2.phpt b/tests/basic/gh17951_runtime_change_2.phpt new file mode 100644 index 00000000000..8bcc5ea65dd --- /dev/null +++ b/tests/basic/gh17951_runtime_change_2.phpt @@ -0,0 +1,14 @@ +--TEST-- +GH-17951 Runtime Change 2 +--CREDITS-- +Frederik Milling Pytlick (frederikpyt@protonmail.com) +--INI-- +memory_limit=128M +max_memory_limit=512M +--FILE-- + +--EXPECT-- +512M diff --git a/tests/basic/gh17951_runtime_change_3.phpt b/tests/basic/gh17951_runtime_change_3.phpt new file mode 100644 index 00000000000..975caad4ff0 --- /dev/null +++ b/tests/basic/gh17951_runtime_change_3.phpt @@ -0,0 +1,15 @@ +--TEST-- +GH-17951 Runtime Change 3 +--CREDITS-- +Frederik Milling Pytlick (frederikpyt@protonmail.com) +--INI-- +memory_limit=128M +max_memory_limit=512M +--FILE-- + +--EXPECTF-- +Warning: Failed to set memory_limit to 1073741824 bytes. Setting to max_memory_limit instead (currently: 536870912 bytes) in %s on line %d +512M diff --git a/tests/basic/gh17951_runtime_change_4.phpt b/tests/basic/gh17951_runtime_change_4.phpt new file mode 100644 index 00000000000..3b27e2c91a9 --- /dev/null +++ b/tests/basic/gh17951_runtime_change_4.phpt @@ -0,0 +1,14 @@ +--TEST-- +GH-17951 Runtime Change 4 +--CREDITS-- +Frederik Milling Pytlick (frederikpyt@protonmail.com) +--INI-- +memory_limit=128M +max_memory_limit=512M +--FILE-- + +--EXPECT-- +512M diff --git a/tests/basic/gh17951_runtime_change_5.phpt b/tests/basic/gh17951_runtime_change_5.phpt new file mode 100644 index 00000000000..f5f5afd6014 --- /dev/null +++ b/tests/basic/gh17951_runtime_change_5.phpt @@ -0,0 +1,19 @@ +--TEST-- +GH-17951 Runtime Change 5 +--CREDITS-- +Frederik Milling Pytlick (frederikpyt@protonmail.com) +--INI-- +memory_limit=128M +max_memory_limit=512M +--FILE-- + +--EXPECT-- +bool(false) +bool(false) +bool(false) +bool(false) diff --git a/tests/lang/033.phpt b/tests/lang/033.phpt index e6254d687b0..41424e40489 100644 --- a/tests/lang/033.phpt +++ b/tests/lang/033.phpt @@ -37,7 +37,8 @@ switch ($a): break; endswitch; ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Case statements followed by a semicolon (;) are deprecated, use a colon (:) instead in %s If: 11 While: 12346789 For: 0123401234 diff --git a/tests/lang/bug26696.phpt b/tests/lang/bug26696.phpt index 1d10297b12c..de0dc90ca0d 100644 --- a/tests/lang/bug26696.phpt +++ b/tests/lang/bug26696.phpt @@ -15,7 +15,7 @@ for ($i = 0; $i < $len; $i++) { $str = '*'; switch ($str[0]) { - case '*'; + case '*': echo "OK\n"; break; default: diff --git a/tests/run-test/extensions-shared.phpt b/tests/run-test/extensions-shared.phpt index 10ad664d383..d4c17f4b092 100644 --- a/tests/run-test/extensions-shared.phpt +++ b/tests/run-test/extensions-shared.phpt @@ -5,7 +5,7 @@ openssl --SKIPIF--