diff --git a/.github/actions/freebsd/action.yml b/.github/actions/freebsd/action.yml index d375a51a6d173..98163d28a82e9 100644 --- a/.github/actions/freebsd/action.yml +++ b/.github/actions/freebsd/action.yml @@ -1,4 +1,8 @@ name: FreeBSD +inputs: + configurationParameters: + default: '' + required: false runs: using: composite steps: @@ -80,7 +84,9 @@ runs: --with-sodium \ --enable-werror \ --with-config-file-path=/etc \ - --with-config-file-scan-dir=/etc/php.d + --with-config-file-scan-dir=/etc/php.d \ + ${{ inputs.configurationParameters }} + gmake -j2 mkdir /etc/php.d gmake install > /dev/null diff --git a/.github/scripts/windows/build.bat b/.github/scripts/windows/build.bat index 65f40fb9462a7..b7beb3a7ef4ba 100644 --- a/.github/scripts/windows/build.bat +++ b/.github/scripts/windows/build.bat @@ -41,7 +41,9 @@ if not exist "%SDK_RUNNER%" ( exit /b 3 ) -cmd /c %SDK_RUNNER% -t .github\scripts\windows\build_task.bat +for /f "delims=" %%T in ('call .github\scripts\windows\find-vs-toolset.bat %PHP_BUILD_CRT%') do set "VS_TOOLSET=%%T" +echo Got VS Toolset %VS_TOOLSET% +cmd /c %SDK_RUNNER% -s %VS_TOOLSET% -t .github\scripts\windows\build_task.bat if %errorlevel% neq 0 exit /b 3 exit /b 0 diff --git a/.github/scripts/windows/find-vs-toolset.bat b/.github/scripts/windows/find-vs-toolset.bat new file mode 100644 index 0000000000000..2d9e68e730318 --- /dev/null +++ b/.github/scripts/windows/find-vs-toolset.bat @@ -0,0 +1,49 @@ +@echo off + +setlocal enabledelayedexpansion + +if "%~1"=="" ( + echo ERROR: Usage: %~nx0 [vc14^|vc15^|vs16^|vs17] + exit /b 1 +) + +set "toolsets_vc14=14.0" +set "toolsets_vc15=" +set "toolsets_vs16=" +set "toolsets_vs17=" + + +for /f "usebackq tokens=*" %%I in (`vswhere.exe -latest -find "VC\Tools\MSVC"`) do set "MSVCDIR=%%I" + +if not defined MSVCDIR ( + echo ERROR: could not locate VC\Tools\MSVC + exit /b 1 +) + +for /f "delims=" %%D in ('dir /b /ad "%MSVCDIR%"') do ( + for /f "tokens=1,2 delims=." %%A in ("%%D") do ( + set "maj=%%A" & set "min=%%B" + if "!maj!"=="14" ( + if !min! LEQ 9 ( + set "toolsets_vc14=%%D" + ) else if !min! LEQ 19 ( + set "toolsets_vc15=%%D" + ) else if !min! LEQ 29 ( + set "toolsets_vs16=%%D" + ) else ( + set "toolsets_vs17=%%D" + ) + ) + ) +) + +set "KEY=%~1" +set "VAR=toolsets_%KEY%" +call set "RESULT=%%%VAR%%%" +if defined RESULT ( + echo %RESULT% + exit /b 0 +) else ( + echo ERROR: no toolset found for %KEY% + exit /b 1 +) diff --git a/.github/scripts/windows/test.bat b/.github/scripts/windows/test.bat index 1a24564697219..b8cc501e0cf3f 100644 --- a/.github/scripts/windows/test.bat +++ b/.github/scripts/windows/test.bat @@ -9,7 +9,8 @@ if not exist "%SDK_RUNNER%" ( exit /b 3 ) -cmd /c %SDK_RUNNER% -t .github\scripts\windows\test_task.bat +for /f "delims=" %%T in ('call .github\scripts\windows\find-vs-toolset.bat %PHP_BUILD_CRT%') do set "VS_TOOLSET=%%T" +cmd /c %SDK_RUNNER% -s %VS_TOOLSET% -t .github\scripts\windows\test_task.bat if %errorlevel% neq 0 exit /b 3 exit /b 0 diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 1b1532af7f799..5817c647a871a 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -23,12 +23,18 @@ on: run_macos_arm64: required: true type: boolean + run_freebsd_zts: + required: true + type: boolean ubuntu_version: required: true type: string windows_version: required: true type: string + vs_crt_version: + required: true + type: string skip_laravel: required: true type: boolean @@ -1031,7 +1037,7 @@ jobs: PHP_BUILD_OBJ_DIR: C:\obj PHP_BUILD_CACHE_SDK_DIR: C:\build-cache\sdk PHP_BUILD_SDK_BRANCH: php-sdk-2.3.0 - PHP_BUILD_CRT: ${{ inputs.windows_version == '2022' && 'vs17' || 'vs16' }} + PHP_BUILD_CRT: ${{ inputs.vs_crt_version }} PLATFORM: ${{ matrix.x64 && 'x64' || 'x86' }} THREAD_SAFE: "${{ matrix.zts && '1' || '0' }}" INTRINSICS: "${{ matrix.zts && 'AVX2' || '' }}" @@ -1052,7 +1058,13 @@ jobs: - name: Test run: .github/scripts/windows/test.bat FREEBSD: - name: FREEBSD + strategy: + fail-fast: false + matrix: + zts: [true, false] + exclude: + - zts: ${{ !inputs.run_freebsd_zts && true || '*never*' }} + name: "FREEBSD_${{ matrix.zts && 'ZTS' || 'NTS' }}" runs-on: ubuntu-latest steps: - name: git checkout @@ -1061,3 +1073,6 @@ jobs: ref: ${{ inputs.branch }} - name: FreeBSD uses: ./.github/actions/freebsd + with: + configurationParameters: >- + --${{ matrix.zts && 'enable' || 'disable' }}-zts diff --git a/.github/workflows/root.yml b/.github/workflows/root.yml index a98bb39ba0d92..96943a8cfb2aa 100644 --- a/.github/workflows/root.yml +++ b/.github/workflows/root.yml @@ -55,10 +55,12 @@ jobs: run_alpine: ${{ (matrix.branch.version[0] == 8 && matrix.branch.version[1] >= 4) || matrix.branch.version[0] >= 9 }} run_linux_ppc64: ${{ (matrix.branch.version[0] == 8 && matrix.branch.version[1] >= 4) || matrix.branch.version[0] >= 9 }} run_macos_arm64: ${{ (matrix.branch.version[0] == 8 && matrix.branch.version[1] >= 4) || matrix.branch.version[0] >= 9 }} + run_freebsd_zts: ${{ (matrix.branch.version[0] == 8 && matrix.branch.version[1] >= 3) || matrix.branch.version[0] >= 9 }} ubuntu_version: ${{ (((matrix.branch.version[0] == 8 && matrix.branch.version[1] >= 5) || matrix.branch.version[0] >= 9) && '24.04') || '22.04' }} - windows_version: ${{ ((matrix.branch.version[0] == 8 && matrix.branch.version[1] >= 4) || matrix.branch.version[0] >= 9) && '2022' || '2019' }} + windows_version: '2022' + vs_crt_version: ${{ ((matrix.branch.version[0] == 8 && matrix.branch.version[1] >= 4) && 'vs17') || 'vs16' }} skip_laravel: ${{ matrix.branch.version[0] == 8 && matrix.branch.version[1] == 1 }} skip_symfony: ${{ matrix.branch.version[0] == 8 && matrix.branch.version[1] == 1 }} skip_wordpress: ${{ matrix.branch.version[0] == 8 && matrix.branch.version[1] == 1 }} diff --git a/.gitignore b/.gitignore index 3c4566ed663c3..1e92e88fb77fa 100644 --- a/.gitignore +++ b/.gitignore @@ -294,6 +294,13 @@ tmp-php.ini /junit.out.xml /.ccache/ +# ------------------------------------------------------------------------------ +# Editor configuration directories +# ------------------------------------------------------------------------------ +/.idea/ +/.vscode/ +/.zed/ + # ------------------------------------------------------------------------------ # Additional test build files # ------------------------------------------------------------------------------ diff --git a/EXTENSIONS b/EXTENSIONS index d15401f372384..01685748b5e09 100644 --- a/EXTENSIONS +++ b/EXTENSIONS @@ -196,7 +196,7 @@ MAINTENANCE: Maintained STATUS: Working ------------------------------------------------------------------------------- EXTENSION: lexbor -PRIMARY MAINTAINER: Niels Dossche (2023 - 2025) +PRIMARY MAINTAINER: Niels Dossche (2025 - 2025) Mate Kocsis (2025 - 2025) MAINTENANCE: Maintained STATUS: Working diff --git a/NEWS b/NEWS index 8f129d715d873..391593dc0c965 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,13 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| -?? ??? ????, PHP 8.5.0alpha1 +?? ??? ????, PHP 8.5.0alpha2 + +- URI: + . Return the singleton UrlValidationErrorType instances from Uri\WhatWg\Url + instead of creating new objects that are different from the singleton. + (timwolla) + +03 Jul 2025, PHP 8.5.0alpha1 - BCMath: . Simplify `bc_divide()` code. (SakiTakamachi) @@ -59,6 +66,7 @@ PHP NEWS . Added support for `final` with constructor property promotion. (DanielEScherzer) . Do not use RTLD_DEEPBIND if dlmopen is available. (Daniil Gentili) + . Make `clone()` a function. (timwolla, edorian) - Curl: . Added curl_multi_get_handles(). (timwolla) @@ -73,6 +81,7 @@ PHP NEWS - DOM: . Added Dom\Element::$outerHTML. (nielsdos) . Added Dom\Element::insertAdjacentHTML(). (nielsdos) + . Added $children property to ParentNode implementations. (nielsdos) - Enchant: . Added enchant_dict_remove_from_session(). (nielsdos) @@ -133,6 +142,9 @@ PHP NEWS - Output: . Fixed calculation of aligned buffer size. (cmb) +- PCNTL: + . Extend pcntl_waitid with rusage parameter. (vrza) + - PCRE: . Upgraded to pre2lib from 10.44 to 10.45. (nielsdos) . Remove PCRE2_EXTRA_ALLOW_LOOKAROUND_BSK from pcre compile options. diff --git a/README.md b/README.md index c5376f67725cd..39c6b89fbbd74 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ blog to the most popular websites in the world. PHP is distributed under the [PHP License v3.01](LICENSE). [![Push](https://github.com/php/php-src/actions/workflows/push.yml/badge.svg)](https://github.com/php/php-src/actions/workflows/push.yml) -[![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/php.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:php) +[![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/php.svg)](https://issues.oss-fuzz.com/issues?q=project:php) ## Documentation @@ -42,28 +42,50 @@ a default build, you will additionally need libxml2 and libsqlite3. On Ubuntu, you can install these using: - sudo apt install -y pkg-config build-essential autoconf bison re2c \ - libxml2-dev libsqlite3-dev +```shell +sudo apt install -y pkg-config build-essential autoconf bison re2c libxml2-dev libsqlite3-dev +``` On Fedora, you can install these using: - sudo dnf install re2c bison autoconf make libtool ccache libxml2-devel sqlite-devel +```shell +sudo dnf install re2c bison autoconf make libtool ccache libxml2-devel sqlite-devel +``` + +On MacOS, you can install these using `brew`: + +```shell +brew install autoconf bison re2c iconv libxml2 sqlite +``` + +or with `MacPorts`: + +```shell +sudo port install autoconf bison re2c libiconv libxml2 sqlite3 +``` Generate configure: - ./buildconf +```shell +./buildconf +``` Configure your build. `--enable-debug` is recommended for development, see `./configure --help` for a full list of options. - # For development - ./configure --enable-debug - # For production - ./configure +```shell +# For development +./configure --enable-debug +# For production +./configure +``` -Build PHP. To speed up the build, specify the maximum number of jobs using `-j`: +Build PHP. To speed up the build, specify the maximum number of jobs using the +`-j` argument: - make -j4 +```shell +make -j4 +``` The number of jobs should usually match the number of available cores, which can be determined using `nproc`. @@ -74,13 +96,21 @@ PHP ships with an extensive test suite, the command `make test` is used after successful compilation of the sources to run this test suite. It is possible to run tests using multiple cores by setting `-jN` in -`TEST_PHP_ARGS`: +`TEST_PHP_ARGS` or `TESTS`: - make TEST_PHP_ARGS=-j4 test +```shell +make TEST_PHP_ARGS=-j4 test +``` Shall run `make test` with a maximum of 4 concurrent jobs: Generally the maximum number of jobs should not exceed the number of cores available. +Use the `TEST_PHP_ARGS` or `TESTS` variable to test only specific directories: + +```shell +make TESTS=tests/lang/ test +``` + The [qa.php.net](https://qa.php.net) site provides more detailed info about testing and quality assurance. @@ -88,9 +118,11 @@ testing and quality assurance. After a successful build (and test), PHP may be installed with: - make install +```shell +make install +``` -Depending on your permissions and prefix, `make install` may need super user +Depending on your permissions and prefix, `make install` may need superuser permissions. ## PHP extensions diff --git a/UPGRADING b/UPGRADING index 4dca8f2b2c213..5491d85f529d8 100644 --- a/UPGRADING +++ b/UPGRADING @@ -185,6 +185,7 @@ PHP 8.5 UPGRADE NOTES - DOM: . Added Dom\Element::$outerHTML. + . Added $children property to Dom\ParentNode implementations. - EXIF: . Add OffsetTime* Exif tags. @@ -289,6 +290,8 @@ PHP 8.5 UPGRADE NOTES - PCNTL: . pcntl_exec() now has a formal return type of false. + . pcntl_waitid() takes an additional resource_usage argument to + gather various platform specific metrics about the child process. - PDO_PGSQL: . PDO::pgsqlCopyFromArray also supports inputs as Iterable. @@ -374,6 +377,8 @@ 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. + RFC: https://wiki.php.net/rfc/clone_with_v2 - Curl: . curl_multi_get_handles() allows retrieving all CurlHandles current diff --git a/UPGRADING.INTERNALS b/UPGRADING.INTERNALS index acc9612b72e30..67c779ea637c8 100644 --- a/UPGRADING.INTERNALS +++ b/UPGRADING.INTERNALS @@ -45,11 +45,17 @@ PHP 8.5 INTERNALS UPGRADE NOTES properties. . ZEND_IS_XDIGIT() macro was removed because it was unused and its name did not match its actual behavior. + . zend_register_constant() now returns a pointer to the added constant + on success and NULL on failure instead of SUCCESS/FAILURE. ======================== 2. Build system changes ======================== +- Abstract + . Preprocessor macro SIZEOF_PTRDIFF_T has been removed. + . Preprocessor macro SIZEOF_INTMAX_T has been removed. + - Windows build system changes . SAPI() and ADD_SOURCES() now suport the optional `duplicate_sources` parameter. If truthy, no rules to build the object files are generated. @@ -66,9 +72,14 @@ PHP 8.5 INTERNALS UPGRADE NOTES . Autoconf macro PHP_AP_EXTRACT_VERSION has been removed. . Autoconf macro PHP_BUILD_THREAD_SAFE has been removed (set enable_zts manually). + . Autoconf macro PHP_CHECK_SIZEOF is obsolete (use AC_CHECK_SIZEOF). . Autoconf macro PHP_DEF_HAVE has been removed (use AC_DEFINE). . Autoconf macro PHP_OUTPUT has been removed (use AC_CONFIG_FILES). . Autoconf macro PHP_TEST_BUILD has been removed (use AC_* macros). + . Preprocessor macro HAVE_PTRDIFF_T has been removed. + . Preprocessor macro HAVE_INTMAX_T has been removed. + . Preprocessor macro HAVE_SSIZE_T has been removed. + . Preprocessor macro SIZEOF_SSIZE_T has been removed. ======================== 3. Module changes diff --git a/Zend/Optimizer/zend_func_infos.h b/Zend/Optimizer/zend_func_infos.h index 3655e5fd21c35..e6a8cea559bc8 100644 --- a/Zend/Optimizer/zend_func_infos.h +++ b/Zend/Optimizer/zend_func_infos.h @@ -1,6 +1,7 @@ /* This is a generated file, edit the .stub.php files instead. */ static const func_info_t func_infos[] = { + F1("clone", MAY_BE_OBJECT), F1("zend_version", MAY_BE_STRING), FN("func_get_args", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_ANY), F1("get_class_vars", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_OF_REF), @@ -394,8 +395,6 @@ static const func_info_t func_infos[] = { F1("compact", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_OF_REF), FN("array_fill", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_ANY), F1("array_fill_keys", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_OF_REF), - F1("array_replace", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_OF_REF), - F1("array_replace_recursive", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_OF_REF), FN("array_keys", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_LONG|MAY_BE_ARRAY_OF_STRING), FN("array_values", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_OF_REF), F1("array_count_values", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_LONG), @@ -404,13 +403,8 @@ static const func_info_t func_infos[] = { F1("array_flip", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_LONG|MAY_BE_ARRAY_OF_STRING), F1("array_change_key_case", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_OF_REF), F1("array_intersect_key", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_OF_REF), - F1("array_intersect_ukey", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_OF_REF), - F1("array_intersect", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_OF_REF), - F1("array_uintersect", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_OF_REF), F1("array_intersect_assoc", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_OF_REF), F1("array_uintersect_assoc", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_OF_REF), - F1("array_intersect_uassoc", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_OF_REF), - F1("array_uintersect_uassoc", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_OF_REF), F1("array_diff_key", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_OF_REF), F1("array_diff_ukey", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_OF_REF), F1("array_udiff", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_OF_REF), diff --git a/Zend/tests/assert/expect_015.phpt b/Zend/tests/assert/expect_015.phpt index 695c4c166a83c..9f8e9b77003bc 100644 --- a/Zend/tests/assert/expect_015.phpt +++ b/Zend/tests/assert/expect_015.phpt @@ -183,7 +183,7 @@ assert(0 && ($a = function () { $x = $a ?? $b; [$a, $b, $c] = [1, 2 => 'x', 'z' => 'c']; @foo(); - $y = clone $x; + $y = \clone($x); yield 1 => 2; yield from $x; })) diff --git a/Zend/tests/attributes/constants/oss_fuzz_428053935.phpt b/Zend/tests/attributes/constants/oss_fuzz_428053935.phpt new file mode 100644 index 0000000000000..97747fd6194fd --- /dev/null +++ b/Zend/tests/attributes/constants/oss_fuzz_428053935.phpt @@ -0,0 +1,19 @@ +--TEST-- +OSS-Fuzz #428053935 +--FILE-- +getAttributes()); +?> +--EXPECTF-- +array(1) { + [0]=> + object(ReflectionAttribute)#%d (1) { + ["name"]=> + string(8) "Foo\Attr" + } +} diff --git a/Zend/tests/bug40770.phpt b/Zend/tests/bug40770.phpt index f37d96d5ff333..bdbae4cf8f1a2 100644 --- a/Zend/tests/bug40770.phpt +++ b/Zend/tests/bug40770.phpt @@ -4,6 +4,9 @@ Bug #40770 (Apache child exits when PHP memory limit reached) memory_limit=8M --SKIPIF-- getMessage(), PHP_EOL; +} + +try { + assert(false && $y = clone($x)); +} catch (Error $e) { + echo $e->getMessage(), PHP_EOL; +} + +try { + assert(false && $y = clone($x, )); +} catch (Error $e) { + echo $e->getMessage(), PHP_EOL; +} + +try { + assert(false && $y = clone($x, [ "foo" => $foo, "bar" => $bar ])); +} catch (Error $e) { + echo $e->getMessage(), PHP_EOL; +} + +try { + assert(false && $y = clone($x, $array)); +} catch (Error $e) { + echo $e->getMessage(), PHP_EOL; +} + +try { + assert(false && $y = clone($x, $array, $extraParameter, $trailingComma, )); +} catch (Error $e) { + echo $e->getMessage(), PHP_EOL; +} + +try { + assert(false && $y = clone(object: $x, withProperties: [ "foo" => $foo, "bar" => $bar ])); +} catch (Error $e) { + echo $e->getMessage(), PHP_EOL; +} + +try { + assert(false && $y = clone($x, withProperties: [ "foo" => $foo, "bar" => $bar ])); +} catch (Error $e) { + echo $e->getMessage(), PHP_EOL; +} + +try { + assert(false && $y = clone(object: $x)); +} catch (Error $e) { + echo $e->getMessage(), PHP_EOL; +} + +try { + assert(false && $y = clone(object: $x, [ "foo" => $foo, "bar" => $bar ])); +} catch (Error $e) { + echo $e->getMessage(), PHP_EOL; +} + +try { + assert(false && $y = clone(...["object" => $x, "withProperties" => [ "foo" => $foo, "bar" => $bar ]])); +} catch (Error $e) { + echo $e->getMessage(), PHP_EOL; +} + +try { + assert(false && $y = clone(...)); +} catch (Error $e) { + echo $e->getMessage(), PHP_EOL; +} + +?> +--EXPECT-- +assert(false && ($y = \clone($x))) +assert(false && ($y = \clone($x))) +assert(false && ($y = \clone($x))) +assert(false && ($y = \clone($x, ['foo' => $foo, 'bar' => $bar]))) +assert(false && ($y = \clone($x, $array))) +assert(false && ($y = \clone($x, $array, $extraParameter, $trailingComma))) +assert(false && ($y = \clone(object: $x, withProperties: ['foo' => $foo, 'bar' => $bar]))) +assert(false && ($y = \clone($x, withProperties: ['foo' => $foo, 'bar' => $bar]))) +assert(false && ($y = \clone(object: $x))) +assert(false && ($y = \clone(object: $x, ['foo' => $foo, 'bar' => $bar]))) +assert(false && ($y = \clone(...['object' => $x, 'withProperties' => ['foo' => $foo, 'bar' => $bar]]))) +assert(false && ($y = \clone(...))) diff --git a/Zend/tests/clone/bug36071.phpt b/Zend/tests/clone/bug36071.phpt index 945118fef3754..e1a4baa7226ee 100644 --- a/Zend/tests/clone/bug36071.phpt +++ b/Zend/tests/clone/bug36071.phpt @@ -4,11 +4,11 @@ Bug #36071 (Engine Crash related with 'clone') error_reporting=4095 --FILE-- b = 0; +try { + $a = clone 0; +} catch (Error $e) { + echo $e::class, ": ", $e->getMessage(), PHP_EOL; +} ?> ---EXPECTF-- -Fatal error: Uncaught Error: __clone method called on non-object in %sbug36071.php:2 -Stack trace: -#0 {main} - thrown in %sbug36071.php on line 2 +--EXPECT-- +TypeError: clone(): Argument #1 ($object) must be of type object, int given diff --git a/Zend/tests/clone/bug42817.phpt b/Zend/tests/clone/bug42817.phpt index a681d861d0c8f..b5f53222d7ee5 100644 --- a/Zend/tests/clone/bug42817.phpt +++ b/Zend/tests/clone/bug42817.phpt @@ -2,11 +2,11 @@ Bug #42817 (clone() on a non-object does not result in a fatal error) --FILE-- b, $c); +try { + $a = clone(null); +} catch (Error $e) { + echo $e::class, ": ", $e->getMessage(), PHP_EOL; +} ?> ---EXPECTF-- -Fatal error: Uncaught Error: __clone method called on non-object in %sbug42817.php:2 -Stack trace: -#0 {main} - thrown in %sbug42817.php on line 2 +--EXPECT-- +TypeError: clone(): Argument #1 ($object) must be of type object, null given diff --git a/Zend/tests/clone/bug42818.phpt b/Zend/tests/clone/bug42818.phpt index b37ce13fd174a..08ba05fcfaa22 100644 --- a/Zend/tests/clone/bug42818.phpt +++ b/Zend/tests/clone/bug42818.phpt @@ -2,10 +2,11 @@ Bug #42818 ($foo = clone(array()); leaks memory) --FILE-- getMessage(), PHP_EOL; +} ?> ---EXPECTF-- -Fatal error: Uncaught Error: __clone method called on non-object in %sbug42818.php:2 -Stack trace: -#0 {main} - thrown in %sbug42818.php on line 2 +--EXPECT-- +TypeError: clone(): Argument #1 ($object) must be of type object, array given diff --git a/Zend/tests/clone/clone_001.phpt b/Zend/tests/clone/clone_001.phpt index 87024c3cd5614..91fa6f551176d 100644 --- a/Zend/tests/clone/clone_001.phpt +++ b/Zend/tests/clone/clone_001.phpt @@ -3,11 +3,12 @@ Using clone statement on non-object --FILE-- getMessage(), PHP_EOL; +} ?> ---EXPECTF-- -Fatal error: Uncaught Error: __clone method called on non-object in %s:%d -Stack trace: -#0 {main} - thrown in %s on line %d +--EXPECT-- +TypeError: clone(): Argument #1 ($object) must be of type object, array given diff --git a/Zend/tests/clone/clone_003.phpt b/Zend/tests/clone/clone_003.phpt index f163616a876dc..b8bb2833dc257 100644 --- a/Zend/tests/clone/clone_003.phpt +++ b/Zend/tests/clone/clone_003.phpt @@ -3,13 +3,13 @@ Using clone statement on undefined variable --FILE-- getMessage(), PHP_EOL; +} ?> --EXPECTF-- Warning: Undefined variable $b in %s on line %d - -Fatal error: Uncaught Error: __clone method called on non-object in %s:%d -Stack trace: -#0 {main} - thrown in %s on line %d +TypeError: clone(): Argument #1 ($object) must be of type object, null given diff --git a/Zend/tests/clone/clone_005.phpt b/Zend/tests/clone/clone_005.phpt new file mode 100644 index 0000000000000..e0366cae67cb5 --- /dev/null +++ b/Zend/tests/clone/clone_005.phpt @@ -0,0 +1,55 @@ +--TEST-- +Clone as a function. +--FILE-- +clone_me()[0]; + +var_dump($f !== $clone); + +?> +--EXPECTF-- +object(stdClass)#%d (0) { +} +array(3) { + [0]=> + object(stdClass)#%d (0) { + } + [1]=> + object(stdClass)#%d (0) { + } + [2]=> + object(stdClass)#%d (0) { + } +} +array(3) { + [0]=> + object(stdClass)#%d (0) { + } + [1]=> + object(stdClass)#%d (0) { + } + [2]=> + object(stdClass)#%d (0) { + } +} +bool(true) diff --git a/Zend/tests/closures/closure_016.phpt b/Zend/tests/closures/closure_016.phpt index 0f87f20f435aa..33860189a57ea 100644 --- a/Zend/tests/closures/closure_016.phpt +++ b/Zend/tests/closures/closure_016.phpt @@ -42,9 +42,9 @@ Foo::__invoke bool(true) Foo::__invoke bool(true) -Closure::__invoke +{closure:foo():9} bool(true) -Closure::__invoke +{closure:foo():9} bool(true) Closure::__invoke bool(true) diff --git a/Zend/tests/closures/gh12073.phpt b/Zend/tests/closures/gh12073.phpt index ef115685ce7d4..811da788d03fc 100644 --- a/Zend/tests/closures/gh12073.phpt +++ b/Zend/tests/closures/gh12073.phpt @@ -2,6 +2,9 @@ GH-12073: Freeing of non-ZMM pointer of incompletely allocated closure --SKIPIF-- --INI-- diff --git a/Zend/tests/gh11189_1.phpt b/Zend/tests/gh11189_1.phpt index 53727908e5e2a..17b9967bc3182 100644 --- a/Zend/tests/gh11189_1.phpt +++ b/Zend/tests/gh11189_1.phpt @@ -2,6 +2,9 @@ GH-11189: Exceeding memory limit in zend_hash_do_resize leaves the array in an invalid state (not packed array) --SKIPIF-- --INI-- diff --git a/Zend/tests/magic_methods/bug73288.phpt b/Zend/tests/magic_methods/bug73288.phpt index 52e8eedeaf013..5e1334cacd07c 100644 --- a/Zend/tests/magic_methods/bug73288.phpt +++ b/Zend/tests/magic_methods/bug73288.phpt @@ -23,6 +23,7 @@ function test_clone() { $b = clone $c->x; } +// No catch, because we want to test Exception::__toString(). test_clone(); ?> --EXPECTF-- diff --git a/Zend/tests/numeric_strings/oss_fuzz_427814456.phpt b/Zend/tests/numeric_strings/oss_fuzz_427814456.phpt new file mode 100644 index 0000000000000..f91563385e9f5 --- /dev/null +++ b/Zend/tests/numeric_strings/oss_fuzz_427814456.phpt @@ -0,0 +1,11 @@ +--TEST-- +OSS-Fuzz #427814456 +--FILE-- + +--EXPECT-- +Done diff --git a/Zend/tests/traits/bugs/gh13177.phpt b/Zend/tests/traits/bugs/gh13177.phpt index 42ef0ae9d60d7..1787b3c6bd7c2 100644 --- a/Zend/tests/traits/bugs/gh13177.phpt +++ b/Zend/tests/traits/bugs/gh13177.phpt @@ -1,5 +1,11 @@ --TEST-- GH-13177 (PHP 8.3.2: final private constructor not allowed when used in trait) +--SKIPIF-- + --FILE-- +--EXPECTF-- +Warning: syntax error, unexpected end of file, expecting '}' in Unknown on line 1 + in %s on line %d +bool(false) diff --git a/Zend/zend_API.c b/Zend/zend_API.c index d29fe8ae8e3c3..e05422395ec19 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -3648,6 +3648,7 @@ static void zend_disable_function(const char *function_name, size_t function_nam if (UNEXPECTED( (function_name_length == strlen("exit") && !memcmp(function_name, "exit", strlen("exit"))) || (function_name_length == strlen("die") && !memcmp(function_name, "die", strlen("die"))) + || (function_name_length == strlen("clone") && !memcmp(function_name, "clone", strlen("clone"))) )) { zend_error(E_WARNING, "Cannot disable function %s()", function_name); return; @@ -4159,13 +4160,10 @@ ZEND_API zend_string *zend_get_callable_name_ex(zval *callable, zend_object *obj if (ce == zend_ce_closure) { const zend_function *fn = zend_get_closure_method_def(Z_OBJ_P(callable)); - if (fn->common.fn_flags & ZEND_ACC_FAKE_CLOSURE) { - if (fn->common.scope) { - return zend_create_member_string(fn->common.scope->name, fn->common.function_name); - } else { - return zend_string_copy(fn->common.function_name); - } + if ((fn->common.fn_flags & ZEND_ACC_FAKE_CLOSURE) && fn->common.scope) { + return zend_create_member_string(fn->common.scope->name, fn->common.function_name); } + return zend_string_copy(fn->common.function_name); } return zend_string_concat2( diff --git a/Zend/zend_ast.c b/Zend/zend_ast.c index cdc86faa95aa3..728695bd9e930 100644 --- a/Zend/zend_ast.c +++ b/Zend/zend_ast.c @@ -2345,8 +2345,6 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio } smart_str_appendc(str, '`'); break; - case ZEND_AST_CLONE: - PREFIX_OP("clone ", 270, 271); case ZEND_AST_PRINT: PREFIX_OP("print ", 60, 61); case ZEND_AST_INCLUDE_OR_EVAL: diff --git a/Zend/zend_ast.h b/Zend/zend_ast.h index c82ca66c9f573..08400cff5dd8e 100644 --- a/Zend/zend_ast.h +++ b/Zend/zend_ast.h @@ -89,7 +89,6 @@ enum _zend_ast_kind { ZEND_AST_ISSET, ZEND_AST_SILENCE, ZEND_AST_SHELL_EXEC, - ZEND_AST_CLONE, ZEND_AST_PRINT, ZEND_AST_INCLUDE_OR_EVAL, ZEND_AST_UNARY_OP, diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c index 7a07ceadce2e2..48e0e86d3b2f8 100644 --- a/Zend/zend_builtin_functions.c +++ b/Zend/zend_builtin_functions.c @@ -69,6 +69,45 @@ zend_result zend_startup_builtin_functions(void) /* {{{ */ } /* }}} */ +ZEND_FUNCTION(clone) +{ + zend_object *zobj; + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_OBJ(zobj) + ZEND_PARSE_PARAMETERS_END(); + + /* clone() also exists as the ZEND_CLONE OPcode and both implementations must be kept in sync. */ + + zend_class_entry *scope = zend_get_executed_scope(); + + zend_class_entry *ce = zobj->ce; + zend_function *clone = ce->clone; + + if (UNEXPECTED(zobj->handlers->clone_obj == NULL)) { + zend_throw_error(NULL, "Trying to clone an uncloneable object of class %s", ZSTR_VAL(ce->name)); + RETURN_THROWS(); + } + + if (clone && !(clone->common.fn_flags & ZEND_ACC_PUBLIC)) { + if (clone->common.scope != scope) { + if (UNEXPECTED(clone->common.fn_flags & ZEND_ACC_PRIVATE) + || UNEXPECTED(!zend_check_protected(zend_get_function_root_class(clone), scope))) { + zend_bad_method_call(clone, clone->common.function_name, scope); + RETURN_THROWS(); + } + } + } + + zend_object *cloned; + cloned = zobj->handlers->clone_obj(zobj); + + ZEND_ASSERT(cloned || EG(exception)); + if (EXPECTED(cloned)) { + RETURN_OBJ(cloned); + } +} + ZEND_FUNCTION(exit) { zend_string *str = NULL; @@ -549,7 +588,7 @@ ZEND_FUNCTION(define) /* non persistent */ ZEND_CONSTANT_SET_FLAGS(&c, 0, PHP_USER_CONSTANT); c.name = zend_string_copy(name); - if (zend_register_constant(&c) == SUCCESS) { + if (zend_register_constant(&c) != NULL) { RETURN_TRUE; } else { RETURN_FALSE; diff --git a/Zend/zend_builtin_functions.stub.php b/Zend/zend_builtin_functions.stub.php index 7f316835aea6b..256c405c71c28 100644 --- a/Zend/zend_builtin_functions.stub.php +++ b/Zend/zend_builtin_functions.stub.php @@ -7,6 +7,9 @@ class stdClass { } +/** @refcount 1 */ +function _clone(object $object): object {} + function exit(string|int $status = 0): never {} /** @alias exit */ diff --git a/Zend/zend_builtin_functions_arginfo.h b/Zend/zend_builtin_functions_arginfo.h index 9498b8292f892..1c595ecd5777c 100644 --- a/Zend/zend_builtin_functions_arginfo.h +++ b/Zend/zend_builtin_functions_arginfo.h @@ -1,5 +1,9 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: a24761186f1ddf758e648b0a764826537cbd33b9 */ + * Stub hash: 12327caa3fe940ccef68ed99f9278982dc0173a5 */ + +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_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_exit, 0, 0, IS_NEVER, 0) ZEND_ARG_TYPE_MASK(0, status, MAY_BE_STRING|MAY_BE_LONG, "0") @@ -243,6 +247,7 @@ static const zend_frameless_function_info frameless_function_infos_class_exists[ { 0 }, }; +ZEND_FUNCTION(clone); ZEND_FUNCTION(exit); ZEND_FUNCTION(zend_version); ZEND_FUNCTION(func_num_args); @@ -306,6 +311,7 @@ ZEND_FUNCTION(gc_disable); ZEND_FUNCTION(gc_status); static const zend_function_entry ext_functions[] = { + ZEND_FE(clone, arginfo_clone) ZEND_FE(exit, arginfo_exit) ZEND_RAW_FENTRY("die", zif_exit, arginfo_die, 0, NULL, NULL) ZEND_FE(zend_version, arginfo_zend_version) diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 28bea1a21d759..f3f6d1b75aec1 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -4930,6 +4930,20 @@ static zend_result zend_compile_func_sprintf(znode *result, zend_ast_list *args) return SUCCESS; } +static zend_result zend_compile_func_clone(znode *result, zend_ast_list *args) +{ + znode arg_node; + + if (args->children != 1) { + return FAILURE; + } + + zend_compile_expr(&arg_node, args->child[0]); + zend_emit_op_tmp(result, ZEND_CLONE, &arg_node, NULL); + + return SUCCESS; +} + static zend_result zend_try_compile_special_func_ex(znode *result, zend_string *lcname, zend_ast_list *args, zend_function *fbc, uint32_t type) /* {{{ */ { if (zend_string_equals_literal(lcname, "strlen")) { @@ -4998,6 +5012,8 @@ static zend_result zend_try_compile_special_func_ex(znode *result, zend_string * return zend_compile_func_array_key_exists(result, args); } else if (zend_string_equals_literal(lcname, "sprintf")) { return zend_compile_func_sprintf(result, args); + } else if (zend_string_equals(lcname, ZSTR_KNOWN(ZEND_STR_CLONE))) { + return zend_compile_func_clone(result, args); } else { return FAILURE; } @@ -5391,17 +5407,6 @@ static void zend_compile_new(znode *result, zend_ast *ast) /* {{{ */ } /* }}} */ -static void zend_compile_clone(znode *result, zend_ast *ast) /* {{{ */ -{ - zend_ast *obj_ast = ast->child[0]; - - znode obj_node; - zend_compile_expr(&obj_node, obj_ast); - - zend_emit_op_tmp(result, ZEND_CLONE, &obj_node, NULL); -} -/* }}} */ - static void zend_compile_global_var(zend_ast *ast) /* {{{ */ { zend_ast *var_ast = ast->child[0]; @@ -11717,9 +11722,6 @@ static void zend_compile_expr_inner(znode *result, zend_ast *ast) /* {{{ */ case ZEND_AST_NEW: zend_compile_new(result, ast); return; - case ZEND_AST_CLONE: - zend_compile_clone(result, ast); - return; case ZEND_AST_ASSIGN_OP: zend_compile_compound_assign(result, ast); return; diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index 62d0fbcded2ee..7ac0a2b8b2c44 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -886,7 +886,6 @@ ZEND_API zend_string *zend_get_compiled_variable_name(const zend_op_array *op_ar #ifdef ZTS const char *zend_get_zendtext(void); -int zend_get_zendleng(void); #endif typedef zend_result (ZEND_FASTCALL *unary_op_type)(zval *, zval *); diff --git a/Zend/zend_constants.c b/Zend/zend_constants.c index ffad8315ae40d..db37b9cf76824 100644 --- a/Zend/zend_constants.c +++ b/Zend/zend_constants.c @@ -505,11 +505,11 @@ static void* zend_hash_add_constant(HashTable *ht, zend_string *key, zend_consta return ret; } -ZEND_API zend_result zend_register_constant(zend_constant *c) +ZEND_API zend_constant *zend_register_constant(zend_constant *c) { zend_string *lowercase_name = NULL; zend_string *name; - zend_result ret = SUCCESS; + zend_constant *ret = NULL; bool persistent = (ZEND_CONSTANT_FLAGS(c) & CONST_PERSISTENT) != 0; #if 0 @@ -539,7 +539,7 @@ ZEND_API zend_result zend_register_constant(zend_constant *c) /* Check if the user is trying to define any special constant */ if (zend_string_equals_literal(name, "__COMPILER_HALT_OFFSET__") || (!persistent && zend_get_special_const(ZSTR_VAL(name), ZSTR_LEN(name))) - || zend_hash_add_constant(EG(zend_constants), name, c) == NULL + || (ret = zend_hash_add_constant(EG(zend_constants), name, c)) == NULL ) { zend_error(E_WARNING, "Constant %s already defined", ZSTR_VAL(name)); zend_string_release(c->name); @@ -550,7 +550,6 @@ ZEND_API zend_result zend_register_constant(zend_constant *c) if (!persistent) { zval_ptr_dtor_nogc(&c->value); } - ret = FAILURE; } if (lowercase_name) { zend_string_release(lowercase_name); diff --git a/Zend/zend_constants.h b/Zend/zend_constants.h index 3912215d80775..69ea1d9021a83 100644 --- a/Zend/zend_constants.h +++ b/Zend/zend_constants.h @@ -97,7 +97,7 @@ ZEND_API void zend_register_long_constant(const char *name, size_t name_len, zen ZEND_API void zend_register_double_constant(const char *name, size_t name_len, double dval, int flags, int module_number); ZEND_API void zend_register_string_constant(const char *name, size_t name_len, const char *strval, int flags, int module_number); ZEND_API void zend_register_stringl_constant(const char *name, size_t name_len, const char *strval, size_t strlen, int flags, int module_number); -ZEND_API zend_result zend_register_constant(zend_constant *c); +ZEND_API zend_constant *zend_register_constant(zend_constant *c); void zend_constant_add_attributes(zend_constant *c, HashTable *attributes); #ifdef ZTS void zend_copy_constants(HashTable *target, HashTable *source); diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 5d8d9f4caeb86..e1593cadce7d0 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -4123,15 +4123,6 @@ static zend_never_inline void zend_fetch_this_var(int type OPLINE_DC EXECUTE_DAT } } -static zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_wrong_clone_call(zend_function *clone, zend_class_entry *scope) -{ - zend_throw_error(NULL, "Call to %s %s::__clone() from %s%s", - zend_visibility_string(clone->common.fn_flags), ZSTR_VAL(clone->common.scope->name), - scope ? "scope " : "global scope", - scope ? ZSTR_VAL(scope->name) : "" - ); -} - #if ZEND_INTENSIVE_DEBUGGING #define CHECK_SYMBOL_TABLES() \ diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 9a7803e44e66e..18e7028957f71 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -438,6 +438,12 @@ void shutdown_executor(void) /* {{{ */ zval *zv; #if ZEND_DEBUG bool fast_shutdown = 0; +#elif defined(__SANITIZE_ADDRESS__) + char *force_fast_shutdown = getenv("ZEND_ASAN_FORCE_FAST_SHUTDOWN"); + bool fast_shutdown = ( + is_zend_mm() + || (force_fast_shutdown && ZEND_ATOL(force_fast_shutdown)) + ) && !EG(full_tables_cleanup); #else bool fast_shutdown = is_zend_mm() && !EG(full_tables_cleanup); #endif diff --git a/Zend/zend_ini_parser.y b/Zend/zend_ini_parser.y index 07df7be88e8c0..5f788f152fb6a 100644 --- a/Zend/zend_ini_parser.y +++ b/Zend/zend_ini_parser.y @@ -353,7 +353,7 @@ static void normalize_value(zval *zv) %left '|' '&' '^' %precedence '~' '!' -%destructor { zval_ini_dtor(&$$); } TC_RAW TC_CONSTANT TC_NUMBER TC_STRING TC_WHITESPACE TC_LABEL TC_OFFSET TC_VARNAME BOOL_TRUE BOOL_FALSE NULL_NULL cfg_var_ref constant_literal constant_string encapsed_list expr option_offset section_string_or_value string_or_value var_string_list var_string_list_section +%destructor { zval_ini_dtor(&$$); } TC_RAW TC_CONSTANT TC_NUMBER TC_STRING TC_WHITESPACE TC_LABEL TC_OFFSET TC_VARNAME BOOL_TRUE BOOL_FALSE NULL_NULL cfg_var_ref constant_literal constant_string encapsed_list expr fallback option_offset section_string_or_value string_or_value var_string_list var_string_list_section %% diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y index 816b8126cbf25..805f378cb983c 100644 --- a/Zend/zend_language_parser.y +++ b/Zend/zend_language_parser.y @@ -259,7 +259,7 @@ static YYSIZE_T zend_yytnamerr(char*, const char*); %type unprefixed_use_declarations const_decl inner_statement %type expr optional_expr while_statement for_statement foreach_variable %type foreach_statement declare_statement finally_statement unset_variable variable -%type extends_from parameter optional_type_without_static argument global_var +%type extends_from parameter optional_type_without_static argument argument_no_expr global_var %type static_var class_statement trait_adaptation trait_precedence trait_alias %type absolute_trait_method_reference trait_method_reference property echo_expr %type new_dereferenceable new_non_dereferenceable anonymous_class class_name class_name_reference simple_variable @@ -287,7 +287,7 @@ static YYSIZE_T zend_yytnamerr(char*, const char*); %type enum_declaration_statement enum_backing_type enum_case enum_case_expr %type function_name non_empty_member_modifiers %type property_hook property_hook_list optional_property_hook_list hooked_property property_hook_body -%type optional_parameter_list +%type optional_parameter_list clone_argument_list non_empty_clone_argument_list %type returns_ref function fn is_reference is_variadic property_modifiers property_hook_modifiers %type method_modifiers class_const_modifiers member_modifier optional_cpp_modifiers @@ -914,13 +914,42 @@ non_empty_argument_list: { $$ = zend_ast_list_add($1, $3); } ; -argument: - expr { $$ = $1; } - | identifier ':' expr +/* `clone_argument_list` is necessary to resolve a parser ambiguity (shift-reduce conflict) + * of `clone($expr)`, which could either be parsed as a function call with `$expr` as the first + * argument or as a use of the `clone` language construct with an expression with useless + * parenthesis. Both would be valid and result in the same AST / the same semantics. + * `clone_argument_list` is defined in a way that an `expr` in the first position needs to + * be followed by a `,` which is not valid syntax for a parenthesized `expr`, ensuring + * that calling `clone()` with a single unnamed parameter is handled by the language construct + * syntax. + */ +clone_argument_list: + '(' ')' { $$ = zend_ast_create_list(0, ZEND_AST_ARG_LIST); } + | '(' non_empty_clone_argument_list possible_comma ')' { $$ = $2; } + | '(' expr ',' ')' { $$ = zend_ast_create_list(1, ZEND_AST_ARG_LIST, $2); } + | '(' T_ELLIPSIS ')' { $$ = zend_ast_create_fcc(); } +; + +non_empty_clone_argument_list: + expr ',' argument + { $$ = zend_ast_create_list(2, ZEND_AST_ARG_LIST, $1, $3); } + | argument_no_expr + { $$ = zend_ast_create_list(1, ZEND_AST_ARG_LIST, $1); } + | non_empty_clone_argument_list ',' argument + { $$ = zend_ast_list_add($1, $3); } +; + +argument_no_expr: + identifier ':' expr { $$ = zend_ast_create(ZEND_AST_NAMED_ARG, $1, $3); } | T_ELLIPSIS expr { $$ = zend_ast_create(ZEND_AST_UNPACK, $2); } ; +argument: + expr { $$ = $1; } + | argument_no_expr { $$ = $1; } +; + global_var_list: global_var_list ',' global_var { $$ = zend_ast_list_add($1, $3); } | global_var { $$ = zend_ast_create_list(1, ZEND_AST_STMT_LIST, $1); } @@ -1228,7 +1257,16 @@ expr: { $$ = zend_ast_create(ZEND_AST_ASSIGN, $1, $3); } | variable '=' ampersand variable { $$ = zend_ast_create(ZEND_AST_ASSIGN_REF, $1, $4); } - | T_CLONE expr { $$ = zend_ast_create(ZEND_AST_CLONE, $2); } + | T_CLONE clone_argument_list { + zend_ast *name = zend_ast_create_zval_from_str(ZSTR_KNOWN(ZEND_STR_CLONE)); + name->attr = ZEND_NAME_FQ; + $$ = zend_ast_create(ZEND_AST_CALL, name, $2); + } + | T_CLONE expr { + zend_ast *name = zend_ast_create_zval_from_str(ZSTR_KNOWN(ZEND_STR_CLONE)); + name->attr = ZEND_NAME_FQ; + $$ = zend_ast_create(ZEND_AST_CALL, name, zend_ast_create_list(1, ZEND_AST_ARG_LIST, $2)); + } | variable T_PLUS_EQUAL expr { $$ = zend_ast_create_assign_op(ZEND_ADD, $1, $3); } | variable T_MINUS_EQUAL expr diff --git a/Zend/zend_lazy_objects.c b/Zend/zend_lazy_objects.c index d1b950160e1cc..cf00804eda33b 100644 --- a/Zend/zend_lazy_objects.c +++ b/Zend/zend_lazy_objects.c @@ -93,7 +93,7 @@ void zend_lazy_objects_destroy(zend_lazy_objects_store *store) zend_hash_destroy(&store->infos); } -static void zend_lazy_object_set_info(zend_object *obj, zend_lazy_object_info *info) +static void zend_lazy_object_set_info(const zend_object *obj, zend_lazy_object_info *info) { ZEND_ASSERT(zend_object_is_lazy(obj)); @@ -102,7 +102,7 @@ static void zend_lazy_object_set_info(zend_object *obj, zend_lazy_object_info *i (void)zv; } -static zend_lazy_object_info* zend_lazy_object_get_info(zend_object *obj) +static zend_lazy_object_info* zend_lazy_object_get_info(const zend_object *obj) { ZEND_ASSERT(zend_object_is_lazy(obj)); @@ -112,7 +112,7 @@ static zend_lazy_object_info* zend_lazy_object_get_info(zend_object *obj) return info; } -static bool zend_lazy_object_has_stale_info(zend_object *obj) +static bool zend_lazy_object_has_stale_info(const zend_object *obj) { return zend_hash_index_find_ptr(&EG(lazy_objects_store).infos, obj->handle); } @@ -154,18 +154,18 @@ zend_object* zend_lazy_object_get_instance(zend_object *obj) return obj; } -zend_lazy_object_flags_t zend_lazy_object_get_flags(zend_object *obj) +zend_lazy_object_flags_t zend_lazy_object_get_flags(const zend_object *obj) { return zend_lazy_object_get_info(obj)->flags; } -void zend_lazy_object_del_info(zend_object *obj) +void zend_lazy_object_del_info(const zend_object *obj) { zend_result res = zend_hash_index_del(&EG(lazy_objects_store).infos, obj->handle); ZEND_ASSERT(res == SUCCESS); } -bool zend_lazy_object_decr_lazy_props(zend_object *obj) +bool zend_lazy_object_decr_lazy_props(const zend_object *obj) { ZEND_ASSERT(zend_object_is_lazy(obj)); ZEND_ASSERT(!zend_lazy_object_initialized(obj)); @@ -183,7 +183,7 @@ bool zend_lazy_object_decr_lazy_props(zend_object *obj) * Making objects lazy */ -ZEND_API bool zend_class_can_be_lazy(zend_class_entry *ce) +ZEND_API bool zend_class_can_be_lazy(const zend_class_entry *ce) { /* Internal classes are not supported */ if (UNEXPECTED(ce->type == ZEND_INTERNAL_CLASS && ce != zend_standard_class_def)) { @@ -444,7 +444,7 @@ static void zend_lazy_object_revert_init(zend_object *obj, zval *properties_tabl OBJ_EXTRA_FLAGS(obj) |= IS_OBJ_LAZY_UNINITIALIZED; } -static bool zend_lazy_object_compatible(zend_object *real_object, zend_object *lazy_object) +static bool zend_lazy_object_compatible(const zend_object *real_object, const zend_object *lazy_object) { if (EXPECTED(real_object->ce == lazy_object->ce)) { return true; diff --git a/Zend/zend_lazy_objects.h b/Zend/zend_lazy_objects.h index 64f68d66360cd..fc0a908e7ad2f 100644 --- a/Zend/zend_lazy_objects.h +++ b/Zend/zend_lazy_objects.h @@ -57,7 +57,7 @@ typedef struct _zend_property_info zend_property_info; typedef struct _zend_fcall_info zend_fcall_info; typedef struct _zend_fcall_info_cache zend_fcall_info_cache; -ZEND_API bool zend_class_can_be_lazy(zend_class_entry *ce); +ZEND_API bool zend_class_can_be_lazy(const zend_class_entry *ce); ZEND_API zend_object *zend_object_make_lazy(zend_object *obj, zend_class_entry *class_type, zval *initializer_zv, zend_fcall_info_cache *initializer_fcc, zend_lazy_object_flags_t flags); @@ -68,39 +68,39 @@ void zend_lazy_objects_init(zend_lazy_objects_store *store); void zend_lazy_objects_destroy(zend_lazy_objects_store *store); zval* zend_lazy_object_get_initializer_zv(zend_object *obj); zend_object *zend_lazy_object_get_instance(zend_object *obj); -zend_lazy_object_flags_t zend_lazy_object_get_flags(zend_object *obj); -void zend_lazy_object_del_info(zend_object *obj); +zend_lazy_object_flags_t zend_lazy_object_get_flags(const zend_object *obj); +void zend_lazy_object_del_info(const zend_object *obj); ZEND_API HashTable *zend_lazy_object_get_properties(zend_object *object); zend_object *zend_lazy_object_clone(zend_object *old_obj); HashTable *zend_lazy_object_debug_info(zend_object *object, int *is_temp); HashTable *zend_lazy_object_get_gc(zend_object *zobj, zval **table, int *n); -bool zend_lazy_object_decr_lazy_props(zend_object *obj); +bool zend_lazy_object_decr_lazy_props(const zend_object *obj); void zend_lazy_object_realize(zend_object *obj); ZEND_API zend_property_info *zend_lazy_object_get_property_info_for_slot(zend_object *obj, zval *slot); -static zend_always_inline bool zend_object_is_lazy(zend_object *obj) +static zend_always_inline bool zend_object_is_lazy(const zend_object *obj) { return (OBJ_EXTRA_FLAGS(obj) & (IS_OBJ_LAZY_UNINITIALIZED | IS_OBJ_LAZY_PROXY)); } -static zend_always_inline bool zend_object_is_lazy_proxy(zend_object *obj) +static zend_always_inline bool zend_object_is_lazy_proxy(const zend_object *obj) { return (OBJ_EXTRA_FLAGS(obj) & IS_OBJ_LAZY_PROXY); } -static zend_always_inline bool zend_lazy_object_initialized(zend_object *obj) +static zend_always_inline bool zend_lazy_object_initialized(const zend_object *obj) { return !(OBJ_EXTRA_FLAGS(obj) & IS_OBJ_LAZY_UNINITIALIZED); } /* True if accessing a lazy prop on obj mandates a call to * zend_lazy_object_init() */ -static zend_always_inline bool zend_lazy_object_must_init(zend_object *obj) +static zend_always_inline bool zend_lazy_object_must_init(const zend_object *obj) { return zend_object_is_lazy(obj); } -static inline bool zend_lazy_object_initialize_on_serialize(zend_object *obj) +static inline bool zend_lazy_object_initialize_on_serialize(const zend_object *obj) { return !(zend_lazy_object_get_flags(obj) & ZEND_LAZY_OBJECT_SKIP_INITIALIZATION_ON_SERIALIZE); } diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index 3d782b03fe174..971df5a7f232a 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -289,7 +289,7 @@ static zend_never_inline int is_protected_compatible_scope(const zend_class_entr } /* }}} */ -static zend_never_inline zend_property_info *zend_get_parent_private_property(zend_class_entry *scope, const zend_class_entry *ce, zend_string *member) /* {{{ */ +static zend_never_inline zend_property_info *zend_get_parent_private_property(const zend_class_entry *scope, const zend_class_entry *ce, zend_string *member) /* {{{ */ { zval *zv; zend_property_info *prop_info; @@ -1823,7 +1823,7 @@ static zend_always_inline zend_function *zend_get_user_call_function(zend_class_ } /* }}} */ -ZEND_API ZEND_COLD zend_never_inline void zend_bad_method_call(zend_function *fbc, zend_string *method_name, zend_class_entry *scope) /* {{{ */ +ZEND_API ZEND_COLD zend_never_inline void zend_bad_method_call(const zend_function *fbc, const zend_string *method_name, const zend_class_entry *scope) /* {{{ */ { zend_throw_error(NULL, "Call to %s method %s::%s() from %s%s", zend_visibility_string(fbc->common.fn_flags), ZEND_FN_SCOPE_NAME(fbc), ZSTR_VAL(method_name), @@ -1833,7 +1833,7 @@ ZEND_API ZEND_COLD zend_never_inline void zend_bad_method_call(zend_function *fb } /* }}} */ -ZEND_API ZEND_COLD zend_never_inline void zend_abstract_method_call(zend_function *fbc) /* {{{ */ +ZEND_API ZEND_COLD zend_never_inline void zend_abstract_method_call(const zend_function *fbc) /* {{{ */ { zend_throw_error(NULL, "Cannot call abstract method %s::%s()", ZSTR_VAL(fbc->common.scope->name), ZSTR_VAL(fbc->common.function_name)); @@ -2090,14 +2090,14 @@ ZEND_API zval *zend_std_get_static_property(zend_class_entry *ce, zend_string *p return zend_std_get_static_property_with_info(ce, property_name, type, &prop_info); } -ZEND_API ZEND_COLD bool zend_std_unset_static_property(zend_class_entry *ce, zend_string *property_name) /* {{{ */ +ZEND_API ZEND_COLD bool zend_std_unset_static_property(const zend_class_entry *ce, const zend_string *property_name) /* {{{ */ { zend_throw_error(NULL, "Attempt to unset static property %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(property_name)); return 0; } /* }}} */ -static ZEND_COLD zend_never_inline void zend_bad_constructor_call(zend_function *constructor, zend_class_entry *scope) /* {{{ */ +static ZEND_COLD zend_never_inline void zend_bad_constructor_call(const zend_function *constructor, const zend_class_entry *scope) /* {{{ */ { if (scope) { zend_throw_error(NULL, "Call to %s %s::%s() from scope %s", diff --git a/Zend/zend_object_handlers.h b/Zend/zend_object_handlers.h index 7e7d3df37a6ad..fb87695a2ed25 100644 --- a/Zend/zend_object_handlers.h +++ b/Zend/zend_object_handlers.h @@ -249,7 +249,7 @@ ZEND_API void zend_class_init_statics(zend_class_entry *ce); ZEND_API zend_function *zend_std_get_static_method(zend_class_entry *ce, zend_string *function_name_strval, const zval *key); ZEND_API zval *zend_std_get_static_property_with_info(zend_class_entry *ce, zend_string *property_name, int type, struct _zend_property_info **prop_info); ZEND_API zval *zend_std_get_static_property(zend_class_entry *ce, zend_string *property_name, int type); -ZEND_API ZEND_COLD bool zend_std_unset_static_property(zend_class_entry *ce, zend_string *property_name); +ZEND_API ZEND_COLD bool zend_std_unset_static_property(const zend_class_entry *ce, const zend_string *property_name); ZEND_API zend_function *zend_std_get_constructor(zend_object *object); ZEND_API struct _zend_property_info *zend_get_property_info(const zend_class_entry *ce, zend_string *member, int silent); ZEND_API HashTable *zend_std_get_properties(zend_object *object); @@ -272,8 +272,8 @@ ZEND_API int zend_std_compare_objects(zval *o1, zval *o2); ZEND_API zend_result zend_std_get_closure(zend_object *obj, zend_class_entry **ce_ptr, zend_function **fptr_ptr, zend_object **obj_ptr, bool check_only); /* Use zend_std_get_properties_ex() */ ZEND_API HashTable *rebuild_object_properties_internal(zend_object *zobj); -ZEND_API ZEND_COLD zend_never_inline void zend_bad_method_call(zend_function *fbc, zend_string *method_name, zend_class_entry *scope); -ZEND_API ZEND_COLD zend_never_inline void zend_abstract_method_call(zend_function *fbc); +ZEND_API ZEND_COLD zend_never_inline void zend_bad_method_call(const zend_function *fbc, const zend_string *method_name, const zend_class_entry *scope); +ZEND_API ZEND_COLD zend_never_inline void zend_abstract_method_call(const zend_function *fbc); static zend_always_inline HashTable *zend_std_get_properties_ex(zend_object *object) { diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c index 712a6039dfb14..bc115e1aa7866 100644 --- a/Zend/zend_operators.c +++ b/Zend/zend_operators.c @@ -402,6 +402,7 @@ static zend_never_inline zend_long ZEND_FASTCALL zendi_try_get_long(const zval * zend_long lval; double dval; bool trailing_data = false; + zend_string *op_str = NULL; /* protect against error handlers */ /* For BC reasons we allow errors so that we can warn on leading numeric string */ type = is_numeric_string_ex(Z_STRVAL_P(op), Z_STRLEN_P(op), &lval, &dval, @@ -411,6 +412,9 @@ static zend_never_inline zend_long ZEND_FASTCALL zendi_try_get_long(const zval * return 0; } if (UNEXPECTED(trailing_data)) { + if (type != IS_LONG) { + op_str = zend_string_copy(Z_STR_P(op)); + } zend_error(E_WARNING, "A non-numeric value encountered"); if (UNEXPECTED(EG(exception))) { *failed = 1; @@ -426,11 +430,12 @@ static zend_never_inline zend_long ZEND_FASTCALL zendi_try_get_long(const zval * */ lval = zend_dval_to_lval_cap(dval); if (!zend_is_long_compatible(dval, lval)) { - zend_incompatible_string_to_long_error(Z_STR_P(op)); + zend_incompatible_string_to_long_error(op_str ? op_str : Z_STR_P(op)); if (UNEXPECTED(EG(exception))) { *failed = 1; } } + zend_tmp_string_release(op_str); return lval; } } diff --git a/Zend/zend_portability.h b/Zend/zend_portability.h index 97bd038ecf3d8..7a41a496a0ed7 100644 --- a/Zend/zend_portability.h +++ b/Zend/zend_portability.h @@ -496,6 +496,8 @@ extern "C++" { #ifdef ZEND_WIN32 #define ZEND_SECURE_ZERO(var, size) RtlSecureZeroMemory((var), (size)) +#elif defined(HAVE_MEMSET_EXPLICIT) +#define ZEND_SECURE_ZERO(var, size) memset_explicit((var), 0, (size)) #else #define ZEND_SECURE_ZERO(var, size) explicit_bzero((var), (size)) #endif diff --git a/Zend/zend_string.h b/Zend/zend_string.h index 0b2a484016ec3..f60e4dec4e71f 100644 --- a/Zend/zend_string.h +++ b/Zend/zend_string.h @@ -575,6 +575,7 @@ EMPTY_SWITCH_DEFAULT_CASE() _(ZEND_STR_UNKNOWN, "unknown") \ _(ZEND_STR_UNKNOWN_CAPITALIZED, "Unknown") \ _(ZEND_STR_EXIT, "exit") \ + _(ZEND_STR_CLONE, "clone") \ _(ZEND_STR_EVAL, "eval") \ _(ZEND_STR_INCLUDE, "include") \ _(ZEND_STR_REQUIRE, "require") \ diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 617e114dd05db..9f7042386a152 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -6006,6 +6006,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. */ + do { if (OP1_TYPE == IS_CONST || (OP1_TYPE != IS_UNUSED && UNEXPECTED(Z_TYPE_P(obj) != IS_OBJECT))) { @@ -6022,7 +6024,7 @@ ZEND_VM_COLD_CONST_HANDLER(110, ZEND_CLONE, CONST|TMPVAR|UNUSED|THIS|CV, ANY) HANDLE_EXCEPTION(); } } - zend_throw_error(NULL, "__clone method called on non-object"); + zend_type_error("clone(): Argument #1 ($object) must be of type object, %s given", zend_zval_value_name(obj)); FREE_OP1(); HANDLE_EXCEPTION(); } @@ -6044,7 +6046,7 @@ ZEND_VM_COLD_CONST_HANDLER(110, ZEND_CLONE, CONST|TMPVAR|UNUSED|THIS|CV, ANY) if (clone->common.scope != scope) { if (UNEXPECTED(clone->common.fn_flags & ZEND_ACC_PRIVATE) || UNEXPECTED(!zend_check_protected(zend_get_function_root_class(clone), scope))) { - zend_wrong_clone_call(clone, scope); + zend_bad_method_call(clone, clone->common.function_name, scope); FREE_OP1(); ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); @@ -8259,7 +8261,7 @@ ZEND_VM_HANDLER(143, ZEND_DECLARE_CONST, CONST, CONST) ZEND_CONSTANT_SET_FLAGS(&c, 0, PHP_USER_CONSTANT); c.name = zend_string_copy(Z_STR_P(name)); - if (zend_register_constant(&c) == FAILURE) { + if (zend_register_constant(&c) == NULL) { } FREE_OP1(); @@ -8272,7 +8274,7 @@ ZEND_VM_HANDLER(210, ZEND_DECLARE_ATTRIBUTED_CONST, CONST, CONST) USE_OPLINE zval *name; zval *val; - zend_constant c; + zend_constant c, *registered; SAVE_OPLINE(); name = GET_OP1_ZVAL_PTR(BP_VAR_R); @@ -8291,7 +8293,8 @@ ZEND_VM_HANDLER(210, ZEND_DECLARE_ATTRIBUTED_CONST, CONST, CONST) ZEND_CONSTANT_SET_FLAGS(&c, 0, PHP_USER_CONSTANT); c.name = zend_string_copy(Z_STR_P(name)); - if (zend_register_constant(&c) == FAILURE) { + registered = zend_register_constant(&c); + if (registered == NULL) { FREE_OP1(); FREE_OP2(); /* two opcodes used, second one is the data with attributes */ @@ -8299,9 +8302,7 @@ ZEND_VM_HANDLER(210, ZEND_DECLARE_ATTRIBUTED_CONST, CONST, CONST) } HashTable *attributes = Z_PTR_P(GET_OP_DATA_ZVAL_PTR(BP_VAR_R)); - zend_constant *registered = zend_get_constant_ptr(c.name); ZEND_ASSERT(attributes != NULL); - ZEND_ASSERT(registered != NULL); zend_constant_add_attributes(registered, attributes); FREE_OP1(); diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 791e4b4e88437..cb2af9e49dd64 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -5180,6 +5180,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. */ + do { if (IS_CONST == IS_CONST || (IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(obj) != IS_OBJECT))) { @@ -5196,7 +5198,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CLONE_SPEC_CONST_ HANDLE_EXCEPTION(); } } - zend_throw_error(NULL, "__clone method called on non-object"); + zend_type_error("clone(): Argument #1 ($object) must be of type object, %s given", zend_zval_value_name(obj)); HANDLE_EXCEPTION(); } @@ -5218,7 +5220,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CLONE_SPEC_CONST_ if (clone->common.scope != scope) { if (UNEXPECTED(clone->common.fn_flags & ZEND_ACC_PRIVATE) || UNEXPECTED(!zend_check_protected(zend_get_function_root_class(clone), scope))) { - zend_wrong_clone_call(clone, scope); + zend_bad_method_call(clone, clone->common.function_name, scope); ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); @@ -8041,7 +8043,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_CONST_SPEC_CONST_CONST ZEND_CONSTANT_SET_FLAGS(&c, 0, PHP_USER_CONSTANT); c.name = zend_string_copy(Z_STR_P(name)); - if (zend_register_constant(&c) == FAILURE) { + if (zend_register_constant(&c) == NULL) { } @@ -8053,7 +8055,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_ATTRIBUTED_CONST_SPEC_ USE_OPLINE zval *name; zval *val; - zend_constant c; + zend_constant c, *registered; SAVE_OPLINE(); name = RT_CONSTANT(opline, opline->op1); @@ -8072,7 +8074,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_ATTRIBUTED_CONST_SPEC_ ZEND_CONSTANT_SET_FLAGS(&c, 0, PHP_USER_CONSTANT); c.name = zend_string_copy(Z_STR_P(name)); - if (zend_register_constant(&c) == FAILURE) { + registered = zend_register_constant(&c); + if (registered == NULL) { /* two opcodes used, second one is the data with attributes */ @@ -8080,9 +8083,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_ATTRIBUTED_CONST_SPEC_ } HashTable *attributes = Z_PTR_P(get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1)); - zend_constant *registered = zend_get_constant_ptr(c.name); ZEND_ASSERT(attributes != NULL); - ZEND_ASSERT(registered != NULL); zend_constant_add_attributes(registered, attributes); @@ -15428,6 +15429,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. */ + do { if ((IS_TMP_VAR|IS_VAR) == IS_CONST || ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_TYPE_P(obj) != IS_OBJECT))) { @@ -15444,7 +15447,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CLONE_SPEC_TMPVAR_HANDLER(ZEND HANDLE_EXCEPTION(); } } - zend_throw_error(NULL, "__clone method called on non-object"); + zend_type_error("clone(): Argument #1 ($object) must be of type object, %s given", zend_zval_value_name(obj)); zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); HANDLE_EXCEPTION(); } @@ -15466,7 +15469,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CLONE_SPEC_TMPVAR_HANDLER(ZEND if (clone->common.scope != scope) { if (UNEXPECTED(clone->common.fn_flags & ZEND_ACC_PRIVATE) || UNEXPECTED(!zend_check_protected(zend_get_function_root_class(clone), scope))) { - zend_wrong_clone_call(clone, scope); + zend_bad_method_call(clone, clone->common.function_name, scope); zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); @@ -33523,6 +33526,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. */ + do { if (IS_UNUSED == IS_CONST || (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(obj) != IS_OBJECT))) { @@ -33539,7 +33544,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CLONE_SPEC_UNUSED_HANDLER(ZEND HANDLE_EXCEPTION(); } } - zend_throw_error(NULL, "__clone method called on non-object"); + zend_type_error("clone(): Argument #1 ($object) must be of type object, %s given", zend_zval_value_name(obj)); HANDLE_EXCEPTION(); } @@ -33561,7 +33566,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CLONE_SPEC_UNUSED_HANDLER(ZEND if (clone->common.scope != scope) { if (UNEXPECTED(clone->common.fn_flags & ZEND_ACC_PRIVATE) || UNEXPECTED(!zend_check_protected(zend_get_function_root_class(clone), scope))) { - zend_wrong_clone_call(clone, scope); + zend_bad_method_call(clone, clone->common.function_name, scope); ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); @@ -41042,6 +41047,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. */ + do { if (IS_CV == IS_CONST || (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(obj) != IS_OBJECT))) { @@ -41058,7 +41065,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CLONE_SPEC_CV_HANDLER(ZEND_OPC HANDLE_EXCEPTION(); } } - zend_throw_error(NULL, "__clone method called on non-object"); + zend_type_error("clone(): Argument #1 ($object) must be of type object, %s given", zend_zval_value_name(obj)); HANDLE_EXCEPTION(); } @@ -41080,7 +41087,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CLONE_SPEC_CV_HANDLER(ZEND_OPC if (clone->common.scope != scope) { if (UNEXPECTED(clone->common.fn_flags & ZEND_ACC_PRIVATE) || UNEXPECTED(!zend_check_protected(zend_get_function_root_class(clone), scope))) { - zend_wrong_clone_call(clone, scope); + zend_bad_method_call(clone, clone->common.function_name, scope); ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); diff --git a/build/gen_stub.php b/build/gen_stub.php index fcef8213d0b55..a3dd14a562346 100755 --- a/build/gen_stub.php +++ b/build/gen_stub.php @@ -1009,6 +1009,9 @@ 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; } @@ -3049,6 +3052,7 @@ class PropertyInfo extends VariableLike "parent" => "ZEND_STR_PARENT", "username" => "ZEND_STR_USERNAME", "password" => "ZEND_STR_PASSWORD", + "clone" => "ZEND_STR_CLONE", ]; /** @@ -4529,7 +4533,7 @@ public function getVariableName(): string { if ($this->name === "param") { // Allow for parsing extended types like callable(string):mixed in docblocks - preg_match('/^\s*(?[\w\|\\\\]+(?\((?(?:(?&parens)|[^(){}[\]]*+))++\)|\{(?&inparens)\}|\[(?&inparens)\])*+(?::(?&type))?)\s*\$(?\w+).*$/', $value, $matches); + preg_match('/^\s*(?[\w\|\\\\]+(?\((?(?:(?&parens)|[^(){}[\]<>]*+))++\)|\{(?&inparens)\}|\[(?&inparens)\]|<(?&inparens)>)*+(?::(?&type))?)\s*\$(?\w+).*$/', $value, $matches); } elseif ($this->name === "prefer-ref") { preg_match('/^\s*\$(?\w+).*$/', $value, $matches); } diff --git a/build/php.m4 b/build/php.m4 index 8cdf318083fbb..db4265c66fc67 100644 --- a/build/php.m4 +++ b/build/php.m4 @@ -1014,7 +1014,9 @@ dnl _PHP_CHECK_SIZEOF(type, cross-value, extra-headers [, found-action [, not-fo dnl dnl Internal helper macro. dnl -AC_DEFUN([_PHP_CHECK_SIZEOF], [ +AC_DEFUN([_PHP_CHECK_SIZEOF], +[m4_warn([obsolete], + [The PHP_CHECK_SIZEOF macro is obsolete. Use AC_CHECK_SIZEOF.]) php_cache_value=php_cv_sizeof_[]$1 AC_CACHE_VAL(php_cv_sizeof_[]$1, [ old_LIBS=$LIBS @@ -1056,6 +1058,9 @@ ifelse([$5],[],,[else $5]) dnl dnl PHP_CHECK_SIZEOF(type, cross-value, extra-headers) dnl +dnl Checks the size of specified "type". This macro is obsolete as of PHP 8.5 in +dnl favor of the AC_CHECK_SIZEOF. +dnl AC_DEFUN([PHP_CHECK_SIZEOF], [ AC_MSG_CHECKING([size of $1]) _PHP_CHECK_SIZEOF($1, $2, $3, [ diff --git a/configure.ac b/configure.ac index e4bd8162a2ebc..663dc32fd28c4 100644 --- a/configure.ac +++ b/configure.ac @@ -451,11 +451,6 @@ AC_CHECK_TYPES([socklen_t], [], [], [ #endif ]) -dnl These are defined elsewhere than stdio.h. -PHP_CHECK_SIZEOF([intmax_t], [0]) -PHP_CHECK_SIZEOF([ssize_t], [8]) -PHP_CHECK_SIZEOF([ptrdiff_t], [8]) - dnl Check stdint types (must be after header check). PHP_CHECK_STDINT_TYPES @@ -565,6 +560,7 @@ AC_CHECK_FUNCS(m4_normalize([ memmem mempcpy memrchr + memset_explicit mkstemp mmap nice diff --git a/docs/release-process.md b/docs/release-process.md index 6eec8ff9f6435..015872096a150 100644 --- a/docs/release-process.md +++ b/docs/release-process.md @@ -96,6 +96,13 @@ releases. `user.signingKey` values to use with your local PHP repositories. See [Conditional Includes For Git Config][] for more information. +11. Any time you see a placeholder like `php-X.Y.ZRCn`, the `RCn` is not always + a release candidate number. The placeholder could also represent any of: + * php-8.4.0alpha1 (initial alpha version) + * php-8.4.0beta2 (one of the beta versions) + * php-8.4.0 (initial GA) + * php-8.4.9 (periodic bugfix or security release) + ## Packaging a non-stable release (alpha/beta/RC) @@ -162,7 +169,10 @@ slightly different steps. We'll call attention where the steps differ. 4. Using your local-only release branch, bump the version numbers in `main/php_version.h`, `Zend/zend.h`, `configure.ac`, and possibly `NEWS`. - + + The date for NEWS should be the date of the announcement (Thursday), + *not* the date of the tagging (Tuesday). + For examples, see [Update versions for PHP 8.1.0beta3][] (for a pre-GA example) or [Update versions for PHP 8.1.6RC1][] along with [Update NEWS for PHP 8.1.6RC1][] (for a post-GA example). @@ -247,9 +257,12 @@ slightly different steps. We'll call attention where the steps differ. ```shell git add -p - git commit --gpg-sign=YOURKEYID -m "[ci skip] Update NEWS for PHP X.Y.Z alpha2" + git commit --gpg-sign=YOURKEYID -m "[ci skip] Update NEWS for PHP X.Y.0 alpha2" ``` + The NEWS is updated at the *start* of the cycle for the next tag, e.g. + [Update NEWS for PHP 8.2.0 alpha2][] was sent as part of tagging 8.2.0 alpha **1**. + 🔷 **For post-GA releases only,** switch back to the *version branch* for your release (e.g., `PHP-8.2`) and bump the version numbers in `main/php_version.h`, `Zend/zend.h`, `configure.ac` and `NEWS`. This prepares @@ -283,7 +296,8 @@ slightly different steps. We'll call attention where the steps differ. ```shell git push upstream php-X.Y.ZRCn # tag name git push upstream PHP-X.Y.Z # patch-level version branch (post-GA only) - git push upstream PHP-X.Y # version branch + git push upstream PHP-X.Y # version branch (post-branch creation only) + git push upstream master # version branch (pre-branch creation only) ``` > 🚨 **Attention** \ @@ -365,6 +379,10 @@ slightly different steps. We'll call attention where the steps differ. Follow the documentation in the file for editing the QA release information. + > 🚨 **Attention** \ + > **For pre-GA releases only,** don't commit yet, because you need to add an + > announcement with the release. After updating `$QA_RELEASES`, skip to step 2 below. + Add, commit, and push your changes, when finished. ```shell @@ -408,6 +426,15 @@ slightly different steps. We'll call attention where the steps differ. text slightly to indicate progression through the pre-release cycle. For example, here are all the news posts for the pre-GA releases of PHP 8.1.0: + > 💬 **Hint** \ + > If you are going to base your language on one of these old announcements, + > remember that + > * `qa.php.net` has been replaced with https://www.php.net/release-candidates.php + > * `bugs.php.net` has been replaced with GitHub issues, use + > `https://github.com/php/php-src/issues/new?template=bug_report.yml` + > to link directly to the form for creating a new bug report. + > * Since 8.4 there have only been 4 release candidates for PHP X.Y.0, rather than 6. + * [Announce 8.1.0alpha1](https://github.com/php/web-php/commit/57b9675c8d8550493289fa1fba77427c93cdd472) * [Announce 8.1.0alpha2](https://github.com/php/web-php/commit/cec044fc0763f5cfa77d0e79479f8b6279023570) * [Announce 8.1.0alpha3](https://github.com/php/web-php/commit/5c480765f444a3fddfd575e01fe0be3fcfdde05b) @@ -431,7 +458,7 @@ slightly different steps. We'll call attention where the steps differ. > When a version is in its post-GA phase, we do not post news entries for > non-stable releases. -3. Wait for the web and qa sites to update with the new information before +3. Wait for the php site to update with the new information before sending announcements. This could take up to an hour. 4. Send *separate* announcement emails to: @@ -447,6 +474,15 @@ slightly different steps. We'll call attention where the steps differ. Here are a few examples of non-stable release announcement emails: + > 💬 **Hint** \ + > If you are going to base your language on one of these old announcements, + > remember that + > * `qa.php.net` has been replaced with https://www.php.net/release-candidates.php + > * `bugs.php.net` has been replaced with GitHub issues, use + > `https://github.com/php/php-src/issues/new?template=bug_report.yml` + > to link directly to the form for creating a new bug report. + > * Since 8.4 there have only been 4 release candidates for PHP X.Y.0, rather than 6. + * [PHP 8.1.0alpha1 is available for testing](https://news-web.php.net/php.qa/69043) * [PHP 8.1.0beta3 available for testing](https://news-web.php.net/php.qa/69079) * [PHP 8.1.0RC6 available for testing](https://news-web.php.net/php.qa/69117) @@ -720,10 +756,10 @@ slightly different steps. We'll call attention where the steps differ. The array probably contains information about the RC released two weeks ago in preparation for the current release. Since the current release is now GA, - it's time to remove the RC build from the QA website. + it's time to remove the RC build from the release candidates page. It is sufficient to set the `number` property for the release to `0` to - stop displaying the RC build on the QA website. You may also remove the + stop displaying the RC build on the release candidates page. You may also remove the sha256 hashes for the RC tarballs, but it's not necessary. 9. Review all the changes in `web-php`, commit, and push them. @@ -981,8 +1017,13 @@ volunteers to begin the selection process for the next release managers. 2. Request membership to the [release managers group](https://github.com/orgs/php/teams/release-managers) on GitHub. -3. Subscribe to the php-announce@lists.php.net mailing list by emailing - php-announce+subscribe@lists.php.net +3. Make sure you are subscribed to all of the mailing lists that you will need to send + announcements to, since you cannot post to the lists otherwise: + + * internals@lists.php.net (email internals+subscribe@lists.php.net) + * php-announce@lists.php.net (email php-announce+subscribe@lists.php.net) + * php-general@lists.php.net (email php-general+subscribe@lists.php.net) + * php-qa@lists.php.net (email php-qa+subscribe@lists.php.net) 4. Email systems@php.net to get setup for access to downloads.php.net, to be added to the release-managers@php.net distribution list, and to be added to diff --git a/ext/curl/curl.stub.php b/ext/curl/curl.stub.php index cbcb52bc7b0a2..00532f45793f5 100644 --- a/ext/curl/curl.stub.php +++ b/ext/curl/curl.stub.php @@ -13,9 +13,9 @@ const CURLOPT_AUTOREFERER = UNKNOWN; /** * @var int - * @deprecated has no effect since 5.1.2 * @cvalue CURLOPT_BINARYTRANSFER */ +#[\Deprecated(since: '8.4', message: 'as it had no effect since 5.1.2')] const CURLOPT_BINARYTRANSFER = UNKNOWN; /** * @var int diff --git a/ext/curl/curl_arginfo.h b/ext/curl/curl_arginfo.h index ef267cd803ba2..cff18b2916859 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: 792cdfa8a8ce190d73dffe679c51a41a2ee46cd7 */ + * Stub hash: c087ac501d0abe14ed87968023d837f358e6fee8 */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_curl_close, 0, 1, IS_VOID, 0) ZEND_ARG_OBJ_INFO(0, handle, CurlHandle, 0) @@ -973,6 +973,20 @@ static void register_curl_symbols(int module_number) REGISTER_LONG_CONSTANT("CURL_HTTP_VERSION_3ONLY", CURL_HTTP_VERSION_3ONLY, CONST_PERSISTENT); #endif REGISTER_LONG_CONSTANT("CURLOPT_SAFE_UPLOAD", CURLOPT_SAFE_UPLOAD, CONST_PERSISTENT); + + zend_constant *const_CURLOPT_BINARYTRANSFER = zend_hash_str_find_ptr(EG(zend_constants), "CURLOPT_BINARYTRANSFER", sizeof("CURLOPT_BINARYTRANSFER") - 1); + + zend_attribute *attribute_Deprecated_const_CURLOPT_BINARYTRANSFER_0 = zend_add_global_constant_attribute(const_CURLOPT_BINARYTRANSFER, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + zval attribute_Deprecated_const_CURLOPT_BINARYTRANSFER_0_arg0; + zend_string *attribute_Deprecated_const_CURLOPT_BINARYTRANSFER_0_arg0_str = zend_string_init("8.4", strlen("8.4"), 1); + ZVAL_STR(&attribute_Deprecated_const_CURLOPT_BINARYTRANSFER_0_arg0, attribute_Deprecated_const_CURLOPT_BINARYTRANSFER_0_arg0_str); + ZVAL_COPY_VALUE(&attribute_Deprecated_const_CURLOPT_BINARYTRANSFER_0->args[0].value, &attribute_Deprecated_const_CURLOPT_BINARYTRANSFER_0_arg0); + 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); + attribute_Deprecated_const_CURLOPT_BINARYTRANSFER_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); } static zend_class_entry *register_class_CurlHandle(void) diff --git a/ext/curl/interface.c b/ext/curl/interface.c index 710f98a13fbb0..4cba1e4d32891 100644 --- a/ext/curl/interface.c +++ b/ext/curl/interface.c @@ -65,6 +65,7 @@ # pragma GCC diagnostic ignored "-Wdeprecated-declarations" #endif +#include "zend_attributes.h" #include "curl_arginfo.h" ZEND_DECLARE_MODULE_GLOBALS(curl) @@ -1411,7 +1412,6 @@ static inline CURLcode add_simple_field(curl_mime *mime, zend_string *string_key part = curl_mime_addpart(mime); if (part == NULL) { zend_tmp_string_release(tmp_postval); - zend_string_release_ex(string_key, 0); return CURLE_OUT_OF_MEMORY; } if ((form_error = curl_mime_name(part, ZSTR_VAL(string_key))) != CURLE_OK diff --git a/ext/curl/tests/bug46711.phpt b/ext/curl/tests/bug46711.phpt index a0b211a7876ab..0540a79bca5b3 100644 --- a/ext/curl/tests/bug46711.phpt +++ b/ext/curl/tests/bug46711.phpt @@ -21,7 +21,7 @@ var_dump($opt); // with this bug, $opt[58] becomes NULL ?> --EXPECTF-- -Deprecated: Constant CURLOPT_BINARYTRANSFER is deprecated in %s on line %d +Deprecated: Constant CURLOPT_BINARYTRANSFER is deprecated since 8.4, as it had no effect since 5.1.2 in %s on line %d array(2) { [58]=> bool(true) diff --git a/ext/date/php_date.stub.php b/ext/date/php_date.stub.php index 7f60be40b1bc8..4f77fc9223e27 100644 --- a/ext/date/php_date.stub.php +++ b/ext/date/php_date.stub.php @@ -83,22 +83,22 @@ /** * @var int * @cvalue SUNFUNCS_RET_TIMESTAMP - * @deprecated */ +#[\Deprecated(since: '8.4', message: 'as date_sunrise() and date_sunset() were deprecated in 8.1')] const SUNFUNCS_RET_TIMESTAMP = UNKNOWN; /** * @var int * @cvalue SUNFUNCS_RET_STRING - * @deprecated */ +#[\Deprecated(since: '8.4', message: 'as date_sunrise() and date_sunset() were deprecated in 8.1')] const SUNFUNCS_RET_STRING = UNKNOWN; /** * @var int * @cvalue SUNFUNCS_RET_DOUBLE - * @deprecated */ +#[\Deprecated(since: '8.4', message: 'as date_sunrise() and date_sunset() were deprecated in 8.1')] const SUNFUNCS_RET_DOUBLE = UNKNOWN; function strtotime(string $datetime, ?int $baseTimestamp = null): int|false {} diff --git a/ext/date/php_date_arginfo.h b/ext/date/php_date_arginfo.h index 2a0fd6e5ac009..0b249c738f715 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: 4e61617ca7c877aa3811d674d47850f23157074b */ + * Stub hash: c9dba59a68085579d18948963a979d63eecff204 */ 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) @@ -860,6 +860,45 @@ static void register_php_date_symbols(int module_number) 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); attribute_Deprecated_func_date_sunset_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + zend_constant *const_SUNFUNCS_RET_TIMESTAMP = zend_hash_str_find_ptr(EG(zend_constants), "SUNFUNCS_RET_TIMESTAMP", sizeof("SUNFUNCS_RET_TIMESTAMP") - 1); + + 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 attribute_Deprecated_const_SUNFUNCS_RET_TIMESTAMP_0_arg0; + zend_string *attribute_Deprecated_const_SUNFUNCS_RET_TIMESTAMP_0_arg0_str = zend_string_init("8.4", strlen("8.4"), 1); + ZVAL_STR(&attribute_Deprecated_const_SUNFUNCS_RET_TIMESTAMP_0_arg0, attribute_Deprecated_const_SUNFUNCS_RET_TIMESTAMP_0_arg0_str); + ZVAL_COPY_VALUE(&attribute_Deprecated_const_SUNFUNCS_RET_TIMESTAMP_0->args[0].value, &attribute_Deprecated_const_SUNFUNCS_RET_TIMESTAMP_0_arg0); + 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); + attribute_Deprecated_const_SUNFUNCS_RET_TIMESTAMP_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + zend_constant *const_SUNFUNCS_RET_STRING = zend_hash_str_find_ptr(EG(zend_constants), "SUNFUNCS_RET_STRING", sizeof("SUNFUNCS_RET_STRING") - 1); + + 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 attribute_Deprecated_const_SUNFUNCS_RET_STRING_0_arg0; + zend_string *attribute_Deprecated_const_SUNFUNCS_RET_STRING_0_arg0_str = zend_string_init("8.4", strlen("8.4"), 1); + ZVAL_STR(&attribute_Deprecated_const_SUNFUNCS_RET_STRING_0_arg0, attribute_Deprecated_const_SUNFUNCS_RET_STRING_0_arg0_str); + ZVAL_COPY_VALUE(&attribute_Deprecated_const_SUNFUNCS_RET_STRING_0->args[0].value, &attribute_Deprecated_const_SUNFUNCS_RET_STRING_0_arg0); + 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); + attribute_Deprecated_const_SUNFUNCS_RET_STRING_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + zend_constant *const_SUNFUNCS_RET_DOUBLE = zend_hash_str_find_ptr(EG(zend_constants), "SUNFUNCS_RET_DOUBLE", sizeof("SUNFUNCS_RET_DOUBLE") - 1); + + 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 attribute_Deprecated_const_SUNFUNCS_RET_DOUBLE_0_arg0; + zend_string *attribute_Deprecated_const_SUNFUNCS_RET_DOUBLE_0_arg0_str = zend_string_init("8.4", strlen("8.4"), 1); + ZVAL_STR(&attribute_Deprecated_const_SUNFUNCS_RET_DOUBLE_0_arg0, attribute_Deprecated_const_SUNFUNCS_RET_DOUBLE_0_arg0_str); + ZVAL_COPY_VALUE(&attribute_Deprecated_const_SUNFUNCS_RET_DOUBLE_0->args[0].value, &attribute_Deprecated_const_SUNFUNCS_RET_DOUBLE_0_arg0); + 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); + attribute_Deprecated_const_SUNFUNCS_RET_DOUBLE_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); } static zend_class_entry *register_class_DateTimeInterface(void) diff --git a/ext/date/tests/bug33536.phpt b/ext/date/tests/bug33536.phpt index aa5f5ddb38bfe..e41fc7f1e2490 100644 --- a/ext/date/tests/bug33536.phpt +++ b/ext/date/tests/bug33536.phpt @@ -4,10 +4,6 @@ Bug #33456 (strtotime defaults to now even on non time string) --EXPECT-- bool(false) -1970-01-01 -1970-01-01 diff --git a/ext/date/tests/bug44780.phpt b/ext/date/tests/bug44780.phpt index 5c822d48e6add..964c619f9b73f 100644 --- a/ext/date/tests/bug44780.phpt +++ b/ext/date/tests/bug44780.phpt @@ -2,8 +2,8 @@ Bug #44780 (some time zone offsets not recognized by timezone_name_from_abbr) --FILE-- --EXPECT-- string(12) "Asia/Kolkata" diff --git a/ext/date/tests/date_sun_info_003.phpt b/ext/date/tests/date_sun_info_003.phpt index 7e74bab621e41..e3cdc93823f2f 100644 --- a/ext/date/tests/date_sun_info_003.phpt +++ b/ext/date/tests/date_sun_info_003.phpt @@ -5,38 +5,43 @@ edgarsandi - --FILE-- $elem ) { - echo "$key: " . date("H:i:s", $elem) . "\n"; + +function print_sun_info(string $date) { + echo $date, "\n"; + $sun_info = date_sun_info(strtotime($date), 89.00, 1.00); + foreach ($sun_info as $key => $elem ) { + echo "$key: " . match ($elem) { + true => 'always', + false => 'never', + default => date("H:i:s", $elem), + } . "\n"; + } } +print_sun_info("2015-01-12 00:00:00 UTC"); echo "\n"; +print_sun_info("2015-09-12 00:00:00 UTC"); -$sun_info = date_sun_info(strtotime("2015-09-12 00:00:00 UTC"), 89.00, 1.00); -foreach ($sun_info as $key => $elem ) { - echo "$key: " . date("H:i:s", $elem) . "\n"; -} - -echo "Done\n"; ?> --EXPECT-- -sunrise: 21:00:00 -sunset: 21:00:00 +2015-01-12 00:00:00 UTC +sunrise: never +sunset: never transit: 10:03:48 -civil_twilight_begin: 21:00:00 -civil_twilight_end: 21:00:00 -nautical_twilight_begin: 21:00:00 -nautical_twilight_end: 21:00:00 -astronomical_twilight_begin: 21:00:00 -astronomical_twilight_end: 21:00:00 +civil_twilight_begin: never +civil_twilight_end: never +nautical_twilight_begin: never +nautical_twilight_end: never +astronomical_twilight_begin: never +astronomical_twilight_end: never -sunrise: 21:00:01 -sunset: 21:00:01 +2015-09-12 00:00:00 UTC +sunrise: always +sunset: always transit: 08:52:44 -civil_twilight_begin: 21:00:01 -civil_twilight_end: 21:00:01 -nautical_twilight_begin: 21:00:01 -nautical_twilight_end: 21:00:01 -astronomical_twilight_begin: 21:00:01 -astronomical_twilight_end: 21:00:01 -Done +civil_twilight_begin: always +civil_twilight_end: always +nautical_twilight_begin: always +nautical_twilight_end: always +astronomical_twilight_begin: always +astronomical_twilight_end: always diff --git a/ext/date/tests/date_sunrise_and_sunset_basic.phpt b/ext/date/tests/date_sunrise_and_sunset_basic.phpt index e5f5efa73e177..d2ed26dea2b6d 100644 --- a/ext/date/tests/date_sunrise_and_sunset_basic.phpt +++ b/ext/date/tests/date_sunrise_and_sunset_basic.phpt @@ -25,12 +25,12 @@ var_dump(gettype(date_sunset(time()))); --EXPECTF-- Basic test for date_sunrise() and date_sunset() -Deprecated: Constant SUNFUNCS_RET_STRING is deprecated in %s on line %d +Deprecated: Constant SUNFUNCS_RET_STRING is deprecated since 8.4, as date_sunrise() and date_sunset() were deprecated in 8.1 in %s on line %d Deprecated: Function date_sunrise() is deprecated since 8.1, use date_sun_info() instead in %s on line %d %s %s %d %d, sunrise time : %d:%d -Deprecated: Constant SUNFUNCS_RET_STRING is deprecated in %s on line %d +Deprecated: Constant SUNFUNCS_RET_STRING is deprecated since 8.4, as date_sunrise() and date_sunset() were deprecated in 8.1 in %s on line %d Deprecated: Function date_sunset() is deprecated since 8.1, use date_sun_info() instead in %s on line %d %s %s %d %d, sunset time : %d:%d diff --git a/ext/date/tests/gh14732.phpt b/ext/date/tests/gh14732.phpt index 63c626963a9d5..19b5f3b481f4b 100644 --- a/ext/date/tests/gh14732.phpt +++ b/ext/date/tests/gh14732.phpt @@ -31,12 +31,12 @@ date_sun_info(): Argument #2 ($latitude) must be finite date_sun_info(): Argument #3 ($longitude) must be finite date_sun_info(): Argument #3 ($longitude) must be finite -Deprecated: Constant SUNFUNCS_RET_STRING is deprecated in %s on line %d +Deprecated: Constant SUNFUNCS_RET_STRING is deprecated since 8.4, as date_sunrise() and date_sunset() were deprecated in 8.1 in %s on line %d Deprecated: Function date_sunset() is deprecated since 8.1, use date_sun_info() instead in %s on line %d bool(false) -Deprecated: Constant SUNFUNCS_RET_STRING is deprecated in %s on line %d +Deprecated: Constant SUNFUNCS_RET_STRING is deprecated since 8.4, as date_sunrise() and date_sunset() were deprecated in 8.1 in %s on line %d Deprecated: Function date_sunrise() is deprecated since 8.1, use date_sun_info() instead in %s on line %d bool(false) diff --git a/ext/date/tests/gh16454.phpt b/ext/date/tests/gh16454.phpt index e3a35a1ba1998..0acad74dce726 100644 --- a/ext/date/tests/gh16454.phpt +++ b/ext/date/tests/gh16454.phpt @@ -8,22 +8,22 @@ var_dump(date_sunset(0, SUNFUNCS_RET_STRING, 61, -150, 90, PHP_FLOAT_MAX)); var_dump(date_sunset(0, SUNFUNCS_RET_STRING, 61, -150, 90, -PHP_FLOAT_MAX)); ?> --EXPECTF-- -Deprecated: Constant SUNFUNCS_RET_STRING is deprecated in %s on line %d +Deprecated: Constant SUNFUNCS_RET_STRING is deprecated since 8.4, as date_sunrise() and date_sunset() were deprecated in 8.1 in %s on line %d Deprecated: Function date_sunrise() is deprecated since 8.1, use date_sun_info() instead in %s on line %d bool(false) -Deprecated: Constant SUNFUNCS_RET_STRING is deprecated in %s on line %d +Deprecated: Constant SUNFUNCS_RET_STRING is deprecated since 8.4, as date_sunrise() and date_sunset() were deprecated in 8.1 in %s on line %d Deprecated: Function date_sunrise() is deprecated since 8.1, use date_sun_info() instead in %s on line %d bool(false) -Deprecated: Constant SUNFUNCS_RET_STRING is deprecated in %s on line %d +Deprecated: Constant SUNFUNCS_RET_STRING is deprecated since 8.4, as date_sunrise() and date_sunset() were deprecated in 8.1 in %s on line %d Deprecated: Function date_sunset() is deprecated since 8.1, use date_sun_info() instead in %s on line %d bool(false) -Deprecated: Constant SUNFUNCS_RET_STRING is deprecated in %s on line %d +Deprecated: Constant SUNFUNCS_RET_STRING is deprecated since 8.4, as date_sunrise() and date_sunset() were deprecated in 8.1 in %s on line %d Deprecated: Function date_sunset() is deprecated since 8.1, use date_sun_info() instead in %s on line %d bool(false) diff --git a/ext/date/tests/gh18481.phpt b/ext/date/tests/gh18481.phpt index 074f244c3a3a3..8c997357e2750 100644 --- a/ext/date/tests/gh18481.phpt +++ b/ext/date/tests/gh18481.phpt @@ -8,22 +8,22 @@ foreach ([-NAN, NAN, INF, -INF] as $offset) { } ?> --EXPECTF-- -Deprecated: Constant SUNFUNCS_RET_STRING is deprecated in %s on line %d +Deprecated: Constant SUNFUNCS_RET_STRING is deprecated since 8.4, as date_sunrise() and date_sunset() were deprecated in 8.1 in %s on line %d Deprecated: Function date_sunrise() is deprecated since 8.1, use date_sun_info() instead in %s on line %d bool(false) -Deprecated: Constant SUNFUNCS_RET_STRING is deprecated in %s on line %d +Deprecated: Constant SUNFUNCS_RET_STRING is deprecated since 8.4, as date_sunrise() and date_sunset() were deprecated in 8.1 in %s on line %d Deprecated: Function date_sunrise() is deprecated since 8.1, use date_sun_info() instead in %s on line %d bool(false) -Deprecated: Constant SUNFUNCS_RET_STRING is deprecated in %s on line %d +Deprecated: Constant SUNFUNCS_RET_STRING is deprecated since 8.4, as date_sunrise() and date_sunset() were deprecated in 8.1 in %s on line %d Deprecated: Function date_sunrise() is deprecated since 8.1, use date_sun_info() instead in %s on line %d bool(false) -Deprecated: Constant SUNFUNCS_RET_STRING is deprecated in %s on line %d +Deprecated: Constant SUNFUNCS_RET_STRING is deprecated since 8.4, as date_sunrise() and date_sunset() were deprecated in 8.1 in %s on line %d Deprecated: Function date_sunrise() is deprecated since 8.1, use date_sun_info() instead in %s on line %d bool(false) diff --git a/ext/dom/dom_properties.h b/ext/dom/dom_properties.h index f9402c929d937..100c6c3d3e78b 100644 --- a/ext/dom/dom_properties.h +++ b/ext/dom/dom_properties.h @@ -109,6 +109,7 @@ zend_result dom_entity_reference_child_nodes_read(dom_object *obj, zval *retval) zend_result dom_namednodemap_length_read(dom_object *obj, zval *retval); /* parent node properties */ +zend_result dom_parent_node_children_read(dom_object *obj, zval *retval); zend_result dom_parent_node_first_element_child_read(dom_object *obj, zval *retval); zend_result dom_parent_node_last_element_child_read(dom_object *obj, zval *retval); zend_result dom_parent_node_child_element_count(dom_object *obj, zval *retval); diff --git a/ext/dom/element.c b/ext/dom/element.c index 27e2845c9f0cb..ea18d0a817ede 100644 --- a/ext/dom/element.c +++ b/ext/dom/element.c @@ -177,18 +177,21 @@ zend_result dom_element_class_name_write(dom_object *obj, zval *newval) } /* }}} */ -zval *dom_element_class_list_zval(dom_object *obj) +zval *dom_get_prop_checked_offset(dom_object *obj, uint32_t offset, const char *name) { - const uint32_t PROP_INDEX = 0; - #if ZEND_DEBUG - zend_string *class_list_str = ZSTR_INIT_LITERAL("classList", false); - const zend_property_info *prop_info = zend_get_property_info(dom_modern_element_class_entry, class_list_str, 0); - zend_string_release_ex(class_list_str, false); - ZEND_ASSERT(OBJ_PROP_TO_NUM(prop_info->offset) == PROP_INDEX); + zend_string *name_zstr = ZSTR_INIT_LITERAL(name, false); + const zend_property_info *prop_info = zend_get_property_info(obj->std.ce, name_zstr, 0); + zend_string_release_ex(name_zstr, false); + ZEND_ASSERT(OBJ_PROP_TO_NUM(prop_info->offset) == offset); #endif - return OBJ_PROP_NUM(&obj->std, PROP_INDEX); + return OBJ_PROP_NUM(&obj->std, offset); +} + +zval *dom_element_class_list_zval(dom_object *obj) +{ + return dom_get_prop_checked_offset(obj, 1, "classList"); } /* {{{ classList TokenList diff --git a/ext/dom/html_collection.c b/ext/dom/html_collection.c index e5dca84de75ff..ce56b77ecd958 100644 --- a/ext/dom/html_collection.c +++ b/ext/dom/html_collection.c @@ -50,12 +50,23 @@ static dom_named_item dom_html_collection_named_item(zend_string *key, zend_obje zend_long cur = 0; zend_long next = cur; /* not +1, otherwise we skip the first candidate */ xmlNodePtr candidate = basep->children; + bool iterate_tag_name = objmap->handler == &php_dom_obj_map_by_tag_name; while (candidate != NULL) { - candidate = dom_get_elements_by_tag_name_ns_raw(basep, candidate, objmap->ns, objmap->local, objmap->local_lower, &cur, next); - if (candidate == NULL) { - break; + if (iterate_tag_name) { + candidate = dom_get_elements_by_tag_name_ns_raw(basep, candidate, objmap->ns, objmap->local, objmap->local_lower, &cur, next); + if (candidate == NULL) { + break; + } + next = cur + 1; + } else { + if (candidate->type != XML_ELEMENT_NODE) { + candidate = candidate->next; + continue; + } } + ZEND_ASSERT(candidate->type == XML_ELEMENT_NODE); + xmlAttrPtr attr; /* it has an ID which is key; */ @@ -73,7 +84,9 @@ static dom_named_item dom_html_collection_named_item(zend_string *key, zend_obje } } - next = cur + 1; + if (!iterate_tag_name) { + candidate = candidate->next; + } } } @@ -141,4 +154,23 @@ int dom_html_collection_has_dimension(zend_object *object, zval *member, int che } } +HashTable *dom_html_collection_get_gc(zend_object *object, zval **table, int *n) +{ + dom_nnodemap_object *objmap = php_dom_obj_from_obj(object)->ptr; + + if (objmap->baseobj) { + zend_get_gc_buffer *gc_buffer = zend_get_gc_buffer_create(); + zend_get_gc_buffer_add_obj(gc_buffer, &objmap->baseobj->std); + zend_get_gc_buffer_use(gc_buffer, table, n); + + if (object->properties == NULL && object->ce->default_properties_count == 0) { + return NULL; + } else { + return zend_std_get_properties(object); + } + } else { + return zend_std_get_gc(object, table, n); + } +} + #endif diff --git a/ext/dom/html_collection.h b/ext/dom/html_collection.h index a94daa1aae805..59ab50abc1b05 100644 --- a/ext/dom/html_collection.h +++ b/ext/dom/html_collection.h @@ -19,5 +19,6 @@ zval *dom_html_collection_read_dimension(zend_object *object, zval *offset, int type, zval *rv); int dom_html_collection_has_dimension(zend_object *object, zval *member, int check_empty); +HashTable *dom_html_collection_get_gc(zend_object *object, zval **table, int *n); #endif diff --git a/ext/dom/html_document.c b/ext/dom/html_document.c index 19d7faef0dbb2..954403ca1c5df 100644 --- a/ext/dom/html_document.c +++ b/ext/dom/html_document.c @@ -84,16 +84,7 @@ typedef struct dom_decoding_encoding_ctx { /* https://dom.spec.whatwg.org/#dom-document-implementation */ zend_result dom_modern_document_implementation_read(dom_object *obj, zval *retval) { - const uint32_t PROP_INDEX = 0; - -#if ZEND_DEBUG - zend_string *implementation_str = ZSTR_INIT_LITERAL("implementation", false); - const zend_property_info *prop_info = zend_get_property_info(dom_abstract_base_document_class_entry, implementation_str, 0); - zend_string_release_ex(implementation_str, false); - ZEND_ASSERT(OBJ_PROP_TO_NUM(prop_info->offset) == PROP_INDEX); -#endif - - zval *cached_implementation = OBJ_PROP_NUM(&obj->std, PROP_INDEX); + zval *cached_implementation = dom_get_prop_checked_offset(obj, 1, "implementation"); if (Z_ISUNDEF_P(cached_implementation)) { php_dom_create_implementation(cached_implementation, true); } diff --git a/ext/dom/obj_map.c b/ext/dom/obj_map.c index fe71a6f47a38a..367171c43007e 100644 --- a/ext/dom/obj_map.c +++ b/ext/dom/obj_map.c @@ -28,10 +28,7 @@ static zend_always_inline void objmap_cache_release_cached_obj(dom_nnodemap_object *objmap) { if (objmap->cached_obj) { - /* Since the DOM is a tree there can be no cycles. */ - if (GC_DELREF(&objmap->cached_obj->std) == 0) { - zend_objects_store_del(&objmap->cached_obj->std); - } + OBJ_RELEASE(&objmap->cached_obj->std); objmap->cached_obj = NULL; objmap->cached_obj_index = 0; } @@ -82,6 +79,20 @@ static zend_long dom_map_get_nodes_length(dom_nnodemap_object *map) return count; } +static zend_long dom_map_get_elements_length(dom_nnodemap_object *map) +{ + zend_long count = 0; + xmlNodePtr nodep = dom_object_get_node(map->baseobj); + if (nodep) { + for (xmlNodePtr curnode = dom_nodelist_iter_start_first_child(nodep); curnode; curnode = curnode->next) { + if (curnode->type == XML_ELEMENT_NODE) { + count++; + } + } + } + return count; +} + static zend_long dom_map_get_by_tag_name_length(dom_nnodemap_object *map) { xmlNodePtr nodep = dom_object_get_node(map->baseobj); @@ -223,6 +234,38 @@ static void dom_map_get_nodes_item(dom_nnodemap_object *map, zend_long index, zv } } +static void dom_map_get_elements_item(dom_nnodemap_object *map, zend_long index, zval *return_value) +{ + xmlNodePtr nodep = dom_object_get_node(map->baseobj); + xmlNodePtr itemnode = NULL; + if (nodep && index >= 0) { + dom_node_idx_pair start_point = dom_obj_map_get_start_point(map, nodep, index); + if (start_point.node) { + /* Guaranteed to be an element */ + itemnode = start_point.node; + } else { + /* Fetch first element child */ + itemnode = nodep->children; + while (itemnode && itemnode->type != XML_ELEMENT_NODE) { + itemnode = itemnode->next; + } + } + + for (; start_point.index > 0 && itemnode; --start_point.index) { + do { + itemnode = itemnode->next; + } while (itemnode && itemnode->type != XML_ELEMENT_NODE); + } + if (itemnode && itemnode->type != XML_ELEMENT_NODE) { + itemnode = NULL; + } + } + dom_ret_node_to_zobj(map, itemnode, return_value); + if (itemnode) { + dom_map_cache_obj(map, itemnode, index, return_value); + } +} + static void dom_map_get_by_tag_name_item(dom_nnodemap_object *map, zend_long index, zval *return_value) { xmlNodePtr nodep = dom_object_get_node(map->baseobj); @@ -456,6 +499,15 @@ const php_dom_obj_map_handler php_dom_obj_map_notations = { .nameless = false, }; +const php_dom_obj_map_handler php_dom_obj_map_child_elements = { + .length = dom_map_get_elements_length, + .get_item = dom_map_get_elements_item, + .get_named_item = dom_map_get_named_item_null, + .has_named_item = dom_map_has_named_item_null, + .use_cache = true, + .nameless = true, +}; + const php_dom_obj_map_handler php_dom_obj_map_noop = { .length = dom_map_get_zero_length, .get_item = dom_map_get_null_item, diff --git a/ext/dom/obj_map.h b/ext/dom/obj_map.h index e1de9addd98f2..dc2b33bd24fec 100644 --- a/ext/dom/obj_map.h +++ b/ext/dom/obj_map.h @@ -57,6 +57,7 @@ zend_long php_dom_get_nodelist_length(dom_object *obj); extern const php_dom_obj_map_handler php_dom_obj_map_attributes; extern const php_dom_obj_map_handler php_dom_obj_map_by_tag_name; +extern const php_dom_obj_map_handler php_dom_obj_map_child_elements; extern const php_dom_obj_map_handler php_dom_obj_map_child_nodes; extern const php_dom_obj_map_handler php_dom_obj_map_nodeset; extern const php_dom_obj_map_handler php_dom_obj_map_entities; diff --git a/ext/dom/parentnode/tree.c b/ext/dom/parentnode/tree.c index f57fd1cc7335b..c51bd2753cd8d 100644 --- a/ext/dom/parentnode/tree.c +++ b/ext/dom/parentnode/tree.c @@ -22,9 +22,34 @@ #include "php.h" #if defined(HAVE_LIBXML) && defined(HAVE_DOM) #include "../php_dom.h" +#include "../obj_map.h" #include "../internal_helpers.h" #include "../dom_properties.h" +zval *dom_parent_node_children(dom_object *obj) +{ + return dom_get_prop_checked_offset(obj, 0, "children"); +} + +zend_result dom_parent_node_children_read(dom_object *obj, zval *retval) +{ + zval *cached_children = dom_parent_node_children(obj); + if (Z_ISUNDEF_P(cached_children)) { + object_init_ex(cached_children, dom_html_collection_class_entry); + php_dom_create_obj_map(obj, Z_DOMOBJ_P(cached_children), NULL, NULL, NULL, &php_dom_obj_map_child_elements); + + /* Handle cycles for potential TMPVARs (could also be CV but we can't differentiate). + * RC == 2 because of 1 TMPVAR and 1 in HTMLCollection. */ + if (GC_REFCOUNT(&obj->std) == 2) { + gc_possible_root(Z_COUNTED_P(cached_children)); + } + } + + ZVAL_OBJ_COPY(retval, Z_OBJ_P(cached_children)); + + return SUCCESS; +} + /* {{{ firstElementChild DomParentNode readonly=yes URL: https://www.w3.org/TR/dom/#dom-parentnode-firstelementchild diff --git a/ext/dom/php_dom.c b/ext/dom/php_dom.c index 6e85ea887e4ec..5df8a1cb1e1ce 100644 --- a/ext/dom/php_dom.c +++ b/ext/dom/php_dom.c @@ -23,6 +23,7 @@ #include "php.h" #if defined(HAVE_LIBXML) && defined(HAVE_DOM) #include "zend_enum.h" +#include "zend_attributes.h" #include "php_dom.h" #include "obj_map.h" #include "nodelist.h" @@ -95,6 +96,7 @@ PHP_DOM_EXPORT zend_class_entry *dom_namespace_info_class_entry; static zend_object_handlers dom_object_handlers; static zend_object_handlers dom_nnodemap_object_handlers; static zend_object_handlers dom_nodelist_object_handlers; +static zend_object_handlers dom_unset_children_property_object_handlers; static zend_object_handlers dom_modern_nnodemap_object_handlers; static zend_object_handlers dom_modern_nodelist_object_handlers; static zend_object_handlers dom_html_collection_object_handlers; @@ -667,14 +669,35 @@ static zend_object *dom_objects_store_clone_obj(zend_object *zobject) /* {{{ */ static zend_object *dom_modern_element_clone_obj(zend_object *zobject) { zend_object *clone = dom_objects_store_clone_obj(zobject); + dom_object *intern = php_dom_obj_from_obj(clone); /* The $classList property is unique per element, and cached due to its [[SameObject]] requirement. * Remove it from the clone so the clone will get a fresh instance upon demand. */ - zval *class_list = dom_element_class_list_zval(php_dom_obj_from_obj(clone)); + zval *class_list = dom_element_class_list_zval(intern); if (!Z_ISUNDEF_P(class_list)) { zval_ptr_dtor(class_list); ZVAL_UNDEF(class_list); } + /* Likewise for $children */ + zval *children = dom_parent_node_children(intern); + if (!Z_ISUNDEF_P(children)) { + zval_ptr_dtor(children); + ZVAL_UNDEF(children); + } + + return clone; +} + +static zend_object *dom_clone_obj_unset_children_property(zend_object *zobject) +{ + zend_object *clone = dom_objects_store_clone_obj(zobject); + dom_object *intern = php_dom_obj_from_obj(clone); + + zval *children = dom_parent_node_children(intern); + if (!Z_ISUNDEF_P(children)) { + zval_ptr_dtor(children); + ZVAL_UNDEF(children); + } return clone; } @@ -776,6 +799,9 @@ PHP_MINIT_FUNCTION(dom) memcpy(&dom_modern_element_object_handlers, &dom_object_handlers, sizeof(zend_object_handlers)); dom_modern_element_object_handlers.clone_obj = dom_modern_element_clone_obj; + memcpy(&dom_unset_children_property_object_handlers, &dom_object_handlers, sizeof(zend_object_handlers)); + dom_unset_children_property_object_handlers.clone_obj = dom_clone_obj_unset_children_property; + memcpy(&dom_nnodemap_object_handlers, &dom_object_handlers, sizeof(zend_object_handlers)); dom_nnodemap_object_handlers.free_obj = dom_nnodemap_objects_free_storage; dom_nnodemap_object_handlers.read_dimension = dom_nodemap_read_dimension; @@ -796,6 +822,8 @@ PHP_MINIT_FUNCTION(dom) memcpy(&dom_html_collection_object_handlers, &dom_modern_nodelist_object_handlers, sizeof(zend_object_handlers)); dom_html_collection_object_handlers.read_dimension = dom_html_collection_read_dimension; dom_html_collection_object_handlers.has_dimension = dom_html_collection_has_dimension; + dom_html_collection_object_handlers.get_gc = dom_html_collection_get_gc; + dom_html_collection_object_handlers.clone_obj = NULL; memcpy(&dom_object_namespace_node_handlers, &dom_object_handlers, sizeof(zend_object_handlers)); dom_object_namespace_node_handlers.offset = XtOffsetOf(dom_object_namespace_node, dom.std); @@ -910,9 +938,10 @@ PHP_MINIT_FUNCTION(dom) dom_modern_documentfragment_class_entry = register_class_Dom_DocumentFragment(dom_modern_node_class_entry, dom_modern_parentnode_class_entry); dom_modern_documentfragment_class_entry->create_object = dom_objects_new; - dom_modern_documentfragment_class_entry->default_object_handlers = &dom_object_handlers; + dom_modern_documentfragment_class_entry->default_object_handlers = &dom_unset_children_property_object_handlers; zend_hash_init(&dom_modern_documentfragment_prop_handlers, 0, NULL, NULL, true); + DOM_REGISTER_PROP_HANDLER(&dom_modern_documentfragment_prop_handlers, "children", dom_parent_node_children_read, NULL); DOM_REGISTER_PROP_HANDLER(&dom_modern_documentfragment_prop_handlers, "firstElementChild", dom_parent_node_first_element_child_read, NULL); DOM_REGISTER_PROP_HANDLER(&dom_modern_documentfragment_prop_handlers, "lastElementChild", dom_parent_node_last_element_child_read, NULL); DOM_REGISTER_PROP_HANDLER(&dom_modern_documentfragment_prop_handlers, "childElementCount", dom_parent_node_child_element_count, NULL); @@ -921,7 +950,7 @@ PHP_MINIT_FUNCTION(dom) zend_hash_add_new_ptr(&classes, dom_modern_documentfragment_class_entry->name, &dom_modern_documentfragment_prop_handlers); dom_abstract_base_document_class_entry = register_class_Dom_Document(dom_modern_node_class_entry, dom_modern_parentnode_class_entry); - dom_abstract_base_document_class_entry->default_object_handlers = &dom_object_handlers; + dom_abstract_base_document_class_entry->default_object_handlers = &dom_unset_children_property_object_handlers; zend_hash_init(&dom_abstract_base_document_prop_handlers, 0, NULL, NULL, true); DOM_REGISTER_PROP_HANDLER(&dom_abstract_base_document_prop_handlers, "implementation", dom_modern_document_implementation_read, NULL); DOM_REGISTER_PROP_HANDLER(&dom_abstract_base_document_prop_handlers, "URL", dom_document_document_uri_read, dom_document_document_uri_write); @@ -931,6 +960,7 @@ PHP_MINIT_FUNCTION(dom) DOM_REGISTER_PROP_HANDLER(&dom_abstract_base_document_prop_handlers, "inputEncoding", dom_document_encoding_read, dom_html_document_encoding_write); DOM_REGISTER_PROP_HANDLER(&dom_abstract_base_document_prop_handlers, "doctype", dom_document_doctype_read, NULL); DOM_REGISTER_PROP_HANDLER(&dom_abstract_base_document_prop_handlers, "documentElement", dom_document_document_element_read, NULL); + DOM_REGISTER_PROP_HANDLER(&dom_abstract_base_document_prop_handlers, "children", dom_parent_node_children_read, NULL); DOM_REGISTER_PROP_HANDLER(&dom_abstract_base_document_prop_handlers, "firstElementChild", dom_parent_node_first_element_child_read, NULL); DOM_REGISTER_PROP_HANDLER(&dom_abstract_base_document_prop_handlers, "lastElementChild", dom_parent_node_last_element_child_read, NULL); DOM_REGISTER_PROP_HANDLER(&dom_abstract_base_document_prop_handlers, "childElementCount", dom_parent_node_child_element_count, NULL); @@ -1117,6 +1147,7 @@ PHP_MINIT_FUNCTION(dom) DOM_REGISTER_PROP_HANDLER(&dom_modern_element_prop_handlers, "className", dom_element_class_name_read, dom_element_class_name_write); DOM_REGISTER_PROP_HANDLER(&dom_modern_element_prop_handlers, "classList", dom_element_class_list_read, NULL); DOM_REGISTER_PROP_HANDLER(&dom_modern_element_prop_handlers, "attributes", dom_node_attributes_read, NULL); + DOM_REGISTER_PROP_HANDLER(&dom_modern_element_prop_handlers, "children", dom_parent_node_children_read, NULL); DOM_REGISTER_PROP_HANDLER(&dom_modern_element_prop_handlers, "firstElementChild", dom_parent_node_first_element_child_read, NULL); DOM_REGISTER_PROP_HANDLER(&dom_modern_element_prop_handlers, "lastElementChild", dom_parent_node_last_element_child_read, NULL); DOM_REGISTER_PROP_HANDLER(&dom_modern_element_prop_handlers, "childElementCount", dom_parent_node_child_element_count, NULL); @@ -1533,8 +1564,8 @@ void dom_nnodemap_objects_free_storage(zend_object *object) /* {{{ */ dom_nnodemap_object *objmap = (dom_nnodemap_object *)intern->ptr; if (objmap) { - if (objmap->cached_obj && GC_DELREF(&objmap->cached_obj->std) == 0) { - zend_objects_store_del(&objmap->cached_obj->std); + if (objmap->cached_obj) { + OBJ_RELEASE(&objmap->cached_obj->std); } if (objmap->release_local) { dom_zend_string_release_from_char_pointer(objmap->local); diff --git a/ext/dom/php_dom.h b/ext/dom/php_dom.h index 0ff8692c4cc74..34cc4af85c568 100644 --- a/ext/dom/php_dom.h +++ b/ext/dom/php_dom.h @@ -160,7 +160,11 @@ bool php_dom_create_nullable_object(xmlNodePtr obj, zval *return_value, dom_obje xmlNodePtr dom_clone_node(php_dom_libxml_ns_mapper *ns_mapper, xmlNodePtr node, xmlDocPtr doc, bool recursive); void dom_set_document_ref_pointers(xmlNodePtr node, php_libxml_ref_obj *document); void dom_set_document_ref_pointers_attr(xmlAttrPtr attr, php_libxml_ref_obj *document); + +/* Prop getters by offset */ +zval *dom_get_prop_checked_offset(dom_object *obj, uint32_t offset, const char *name); zval *dom_element_class_list_zval(dom_object *obj); +zval *dom_parent_node_children(dom_object *obj); typedef enum { DOM_LOAD_STRING = 0, diff --git a/ext/dom/php_dom.stub.php b/ext/dom/php_dom.stub.php index 43d26ec7a3c7d..fd0927fc0ea12 100644 --- a/ext/dom/php_dom.stub.php +++ b/ext/dom/php_dom.stub.php @@ -147,9 +147,9 @@ /** * @var int - * @deprecated is no longer used since 8.4 * @cvalue PHP_ERR */ + #[\Deprecated(since: '8.4', message: 'as it is no longer used')] const DOM_PHP_ERR = UNKNOWN; /** * @var int @@ -1584,6 +1584,36 @@ class Element extends Node implements ParentNode, ChildNode */ public string $tagName; + /** + * @readonly + */ + public HTMLCollection $children; + /** + * @readonly + * @virtual + */ + public ?Element $firstElementChild; + /** + * @readonly + * @virtual + */ + public ?Element $lastElementChild; + /** + * @readonly + * @virtual + */ + public int $childElementCount; + /** + * @readonly + * @virtual + */ + public ?Element $previousElementSibling; + /** + * @readonly + * @virtual + */ + public ?Element $nextElementSibling; + /** @virtual */ public string $id; /** @virtual */ @@ -1634,32 +1664,6 @@ public function insertAdjacentElement(AdjacentPosition $where, Element $element) public function insertAdjacentText(AdjacentPosition $where, string $data): void {} public function insertAdjacentHTML(AdjacentPosition $where, string $string): void {} - /** - * @readonly - * @virtual - */ - public ?Element $firstElementChild; - /** - * @readonly - * @virtual - */ - public ?Element $lastElementChild; - /** - * @readonly - * @virtual - */ - public int $childElementCount; - /** - * @readonly - * @virtual - */ - public ?Element $previousElementSibling; - /** - * @readonly - * @virtual - */ - public ?Element $nextElementSibling; - /** @implementation-alias DOMElement::setIdAttribute */ public function setIdAttribute(string $qualifiedName, bool $isId): void {} /** @implementation-alias DOMElement::setIdAttributeNS */ @@ -1863,6 +1867,10 @@ public function replaceWith(Node|string ...$nodes): void {} class DocumentFragment extends Node implements ParentNode { + /** + * @readonly + */ + public HTMLCollection $children; /** * @readonly * @virtual @@ -1931,6 +1939,26 @@ class Notation extends Node abstract class Document extends Node implements ParentNode { + /** + * @readonly + */ + public HTMLCollection $children; + /** + * @readonly + * @virtual + */ + public ?Element $firstElementChild; + /** + * @readonly + * @virtual + */ + public ?Element $lastElementChild; + /** + * @readonly + * @virtual + */ + public int $childElementCount; + /** @readonly */ public Implementation $implementation; /** @virtual */ @@ -1979,22 +2007,6 @@ public function createAttribute(string $localName): Attr {} /** @implementation-alias DOMDocument::createAttributeNS */ public function createAttributeNS(?string $namespace, string $qualifiedName): Attr {} - /** - * @readonly - * @virtual - */ - public ?Element $firstElementChild; - /** - * @readonly - * @virtual - */ - public ?Element $lastElementChild; - /** - * @readonly - * @virtual - */ - public int $childElementCount; - /** @implementation-alias DOMDocument::getElementById */ public function getElementById(string $elementId): ?Element {} diff --git a/ext/dom/php_dom_arginfo.h b/ext/dom/php_dom_arginfo.h index 5c21b909b0e18..922f03240e0f8 100644 --- a/ext/dom/php_dom_arginfo.h +++ b/ext/dom/php_dom_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 0fcee2fa666dc88faf084578dde157409a6f5594 */ + * Stub hash: 2119512797f6d51d9835660cd0eccd3ba83417a9 */ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_dom_import_simplexml, 0, 1, DOMAttr|DOMElement, 0) ZEND_ARG_TYPE_INFO(0, node, IS_OBJECT, 0) @@ -1870,6 +1870,20 @@ static void register_php_dom_symbols(int module_number) REGISTER_LONG_CONSTANT("Dom\\NAMESPACE_ERR", NAMESPACE_ERR, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("Dom\\VALIDATION_ERR", VALIDATION_ERR, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("Dom\\HTML_NO_DEFAULT_NS", DOM_HTML_NO_DEFAULT_NS, CONST_PERSISTENT); + + zend_constant *const_DOM_PHP_ERR = zend_hash_str_find_ptr(EG(zend_constants), "DOM_PHP_ERR", sizeof("DOM_PHP_ERR") - 1); + + 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 attribute_Deprecated_const_DOM_PHP_ERR_0_arg0; + zend_string *attribute_Deprecated_const_DOM_PHP_ERR_0_arg0_str = zend_string_init("8.4", strlen("8.4"), 1); + ZVAL_STR(&attribute_Deprecated_const_DOM_PHP_ERR_0_arg0, attribute_Deprecated_const_DOM_PHP_ERR_0_arg0_str); + ZVAL_COPY_VALUE(&attribute_Deprecated_const_DOM_PHP_ERR_0->args[0].value, &attribute_Deprecated_const_DOM_PHP_ERR_0_arg0); + 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); + attribute_Deprecated_const_DOM_PHP_ERR_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); } static zend_class_entry *register_class_DOMDocumentType(zend_class_entry *class_entry_DOMNode) @@ -3011,31 +3025,12 @@ static zend_class_entry *register_class_Dom_Element(zend_class_entry *class_entr zend_declare_typed_property(class_entry, property_tagName_name, &property_tagName_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_tagName_name); - zval property_id_default_value; - ZVAL_UNDEF(&property_id_default_value); - zend_string *property_id_name = zend_string_init("id", sizeof("id") - 1, 1); - zend_declare_typed_property(class_entry, property_id_name, &property_id_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); - zend_string_release(property_id_name); - - zval property_className_default_value; - ZVAL_UNDEF(&property_className_default_value); - zend_string *property_className_name = zend_string_init("className", sizeof("className") - 1, 1); - zend_declare_typed_property(class_entry, property_className_name, &property_className_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); - zend_string_release(property_className_name); - - zval property_classList_default_value; - ZVAL_UNDEF(&property_classList_default_value); - zend_string *property_classList_name = zend_string_init("classList", sizeof("classList") - 1, 1); - zend_string *property_classList_class_Dom_TokenList = zend_string_init("Dom\\TokenList", sizeof("Dom\\TokenList")-1, 1); - zend_declare_typed_property(class_entry, property_classList_name, &property_classList_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_classList_class_Dom_TokenList, 0, 0)); - zend_string_release(property_classList_name); - - zval property_attributes_default_value; - ZVAL_UNDEF(&property_attributes_default_value); - zend_string *property_attributes_name = zend_string_init("attributes", sizeof("attributes") - 1, 1); - zend_string *property_attributes_class_Dom_NamedNodeMap = zend_string_init("Dom\\\116amedNodeMap", sizeof("Dom\\\116amedNodeMap")-1, 1); - zend_declare_typed_property(class_entry, property_attributes_name, &property_attributes_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_attributes_class_Dom_NamedNodeMap, 0, 0)); - zend_string_release(property_attributes_name); + zval property_children_default_value; + ZVAL_UNDEF(&property_children_default_value); + zend_string *property_children_name = zend_string_init("children", sizeof("children") - 1, 1); + zend_string *property_children_class_Dom_HTMLCollection = zend_string_init("Dom\\HTMLCollection", sizeof("Dom\\HTMLCollection")-1, 1); + zend_declare_typed_property(class_entry, property_children_name, &property_children_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_children_class_Dom_HTMLCollection, 0, 0)); + zend_string_release(property_children_name); zval property_firstElementChild_default_value; ZVAL_UNDEF(&property_firstElementChild_default_value); @@ -3071,6 +3066,32 @@ static zend_class_entry *register_class_Dom_Element(zend_class_entry *class_entr zend_declare_typed_property(class_entry, property_nextElementSibling_name, &property_nextElementSibling_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_nextElementSibling_class_Dom_Element, 0, MAY_BE_NULL)); zend_string_release(property_nextElementSibling_name); + zval property_id_default_value; + ZVAL_UNDEF(&property_id_default_value); + zend_string *property_id_name = zend_string_init("id", sizeof("id") - 1, 1); + zend_declare_typed_property(class_entry, property_id_name, &property_id_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_string_release(property_id_name); + + zval property_className_default_value; + ZVAL_UNDEF(&property_className_default_value); + zend_string *property_className_name = zend_string_init("className", sizeof("className") - 1, 1); + zend_declare_typed_property(class_entry, property_className_name, &property_className_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_string_release(property_className_name); + + zval property_classList_default_value; + ZVAL_UNDEF(&property_classList_default_value); + zend_string *property_classList_name = zend_string_init("classList", sizeof("classList") - 1, 1); + zend_string *property_classList_class_Dom_TokenList = zend_string_init("Dom\\TokenList", sizeof("Dom\\TokenList")-1, 1); + zend_declare_typed_property(class_entry, property_classList_name, &property_classList_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_classList_class_Dom_TokenList, 0, 0)); + zend_string_release(property_classList_name); + + zval property_attributes_default_value; + ZVAL_UNDEF(&property_attributes_default_value); + zend_string *property_attributes_name = zend_string_init("attributes", sizeof("attributes") - 1, 1); + zend_string *property_attributes_class_Dom_NamedNodeMap = zend_string_init("Dom\\\116amedNodeMap", sizeof("Dom\\\116amedNodeMap")-1, 1); + zend_declare_typed_property(class_entry, property_attributes_name, &property_attributes_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_attributes_class_Dom_NamedNodeMap, 0, 0)); + zend_string_release(property_attributes_name); + zval property_innerHTML_default_value; ZVAL_UNDEF(&property_innerHTML_default_value); zend_string *property_innerHTML_name = zend_string_init("innerHTML", sizeof("innerHTML") - 1, 1); @@ -3295,6 +3316,13 @@ static zend_class_entry *register_class_Dom_DocumentFragment(zend_class_entry *c class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Dom_Node, 0); zend_class_implements(class_entry, 1, class_entry_Dom_ParentNode); + zval property_children_default_value; + ZVAL_UNDEF(&property_children_default_value); + zend_string *property_children_name = zend_string_init("children", sizeof("children") - 1, 1); + zend_string *property_children_class_Dom_HTMLCollection = zend_string_init("Dom\\HTMLCollection", sizeof("Dom\\HTMLCollection")-1, 1); + zend_declare_typed_property(class_entry, property_children_name, &property_children_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_children_class_Dom_HTMLCollection, 0, 0)); + zend_string_release(property_children_name); + zval property_firstElementChild_default_value; ZVAL_UNDEF(&property_firstElementChild_default_value); zend_string *property_firstElementChild_name = zend_string_init("firstElementChild", sizeof("firstElementChild") - 1, 1); @@ -3386,6 +3414,33 @@ static zend_class_entry *register_class_Dom_Document(zend_class_entry *class_ent class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Dom_Node, ZEND_ACC_ABSTRACT); zend_class_implements(class_entry, 1, class_entry_Dom_ParentNode); + zval property_children_default_value; + ZVAL_UNDEF(&property_children_default_value); + zend_string *property_children_name = zend_string_init("children", sizeof("children") - 1, 1); + zend_string *property_children_class_Dom_HTMLCollection = zend_string_init("Dom\\HTMLCollection", sizeof("Dom\\HTMLCollection")-1, 1); + zend_declare_typed_property(class_entry, property_children_name, &property_children_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_children_class_Dom_HTMLCollection, 0, 0)); + zend_string_release(property_children_name); + + zval property_firstElementChild_default_value; + ZVAL_UNDEF(&property_firstElementChild_default_value); + zend_string *property_firstElementChild_name = zend_string_init("firstElementChild", sizeof("firstElementChild") - 1, 1); + zend_string *property_firstElementChild_class_Dom_Element = zend_string_init("Dom\\Element", sizeof("Dom\\Element")-1, 1); + zend_declare_typed_property(class_entry, property_firstElementChild_name, &property_firstElementChild_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_firstElementChild_class_Dom_Element, 0, MAY_BE_NULL)); + zend_string_release(property_firstElementChild_name); + + zval property_lastElementChild_default_value; + ZVAL_UNDEF(&property_lastElementChild_default_value); + zend_string *property_lastElementChild_name = zend_string_init("lastElementChild", sizeof("lastElementChild") - 1, 1); + zend_string *property_lastElementChild_class_Dom_Element = zend_string_init("Dom\\Element", sizeof("Dom\\Element")-1, 1); + zend_declare_typed_property(class_entry, property_lastElementChild_name, &property_lastElementChild_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_lastElementChild_class_Dom_Element, 0, MAY_BE_NULL)); + zend_string_release(property_lastElementChild_name); + + zval property_childElementCount_default_value; + ZVAL_UNDEF(&property_childElementCount_default_value); + zend_string *property_childElementCount_name = zend_string_init("childElementCount", sizeof("childElementCount") - 1, 1); + zend_declare_typed_property(class_entry, property_childElementCount_name, &property_childElementCount_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(property_childElementCount_name); + zval property_implementation_default_value; ZVAL_UNDEF(&property_implementation_default_value); zend_string *property_implementation_name = zend_string_init("implementation", sizeof("implementation") - 1, 1); @@ -3437,26 +3492,6 @@ static zend_class_entry *register_class_Dom_Document(zend_class_entry *class_ent zend_declare_typed_property(class_entry, property_documentElement_name, &property_documentElement_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_documentElement_class_Dom_Element, 0, MAY_BE_NULL)); zend_string_release(property_documentElement_name); - zval property_firstElementChild_default_value; - ZVAL_UNDEF(&property_firstElementChild_default_value); - zend_string *property_firstElementChild_name = zend_string_init("firstElementChild", sizeof("firstElementChild") - 1, 1); - zend_string *property_firstElementChild_class_Dom_Element = zend_string_init("Dom\\Element", sizeof("Dom\\Element")-1, 1); - zend_declare_typed_property(class_entry, property_firstElementChild_name, &property_firstElementChild_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_firstElementChild_class_Dom_Element, 0, MAY_BE_NULL)); - zend_string_release(property_firstElementChild_name); - - zval property_lastElementChild_default_value; - ZVAL_UNDEF(&property_lastElementChild_default_value); - zend_string *property_lastElementChild_name = zend_string_init("lastElementChild", sizeof("lastElementChild") - 1, 1); - zend_string *property_lastElementChild_class_Dom_Element = zend_string_init("Dom\\Element", sizeof("Dom\\Element")-1, 1); - zend_declare_typed_property(class_entry, property_lastElementChild_name, &property_lastElementChild_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_lastElementChild_class_Dom_Element, 0, MAY_BE_NULL)); - zend_string_release(property_lastElementChild_name); - - zval property_childElementCount_default_value; - ZVAL_UNDEF(&property_childElementCount_default_value); - zend_string *property_childElementCount_name = zend_string_init("childElementCount", sizeof("childElementCount") - 1, 1); - zend_declare_typed_property(class_entry, property_childElementCount_name, &property_childElementCount_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(property_childElementCount_name); - zval property_body_default_value; ZVAL_UNDEF(&property_body_default_value); zend_string *property_body_name = zend_string_init("body", sizeof("body") - 1, 1); diff --git a/ext/dom/tests/DOM_PHP_ERR_deprecated.phpt b/ext/dom/tests/DOM_PHP_ERR_deprecated.phpt index 76bd2757e7b5c..1dad517927206 100644 --- a/ext/dom/tests/DOM_PHP_ERR_deprecated.phpt +++ b/ext/dom/tests/DOM_PHP_ERR_deprecated.phpt @@ -7,5 +7,5 @@ dom var_dump(DOM_PHP_ERR); ?> --EXPECTF-- -Deprecated: Constant DOM_PHP_ERR is deprecated in %s on line %d +Deprecated: Constant DOM_PHP_ERR is deprecated since 8.4, as it is no longer used in %s on line %d int(0) diff --git a/ext/dom/tests/gh15192.phpt b/ext/dom/tests/gh15192.phpt index c7bf0a543bb93..f6031c2a40b02 100644 --- a/ext/dom/tests/gh15192.phpt +++ b/ext/dom/tests/gh15192.phpt @@ -11,7 +11,7 @@ $dom = new DomDocument(); var_dump($element); ?> --EXPECT-- -object(Dom\HTMLElement)#3 (30) { +object(Dom\HTMLElement)#3 (31) { ["namespaceURI"]=> string(28) "http://www.w3.org/1999/xhtml" ["prefix"]=> @@ -28,6 +28,8 @@ object(Dom\HTMLElement)#3 (30) { string(22) "(object value omitted)" ["attributes"]=> string(22) "(object value omitted)" + ["children"]=> + string(22) "(object value omitted)" ["firstElementChild"]=> string(22) "(object value omitted)" ["lastElementChild"]=> diff --git a/ext/dom/tests/gh16356.phpt b/ext/dom/tests/gh16356.phpt index ad09c2681806e..53d90d8490e29 100644 --- a/ext/dom/tests/gh16356.phpt +++ b/ext/dom/tests/gh16356.phpt @@ -13,7 +13,7 @@ var_dump($e1, $e2); ?> --EXPECT-- -object(Dom\Element)#3 (30) { +object(Dom\Element)#3 (31) { ["namespaceURI"]=> string(12) "urn:example1" ["prefix"]=> @@ -30,6 +30,8 @@ object(Dom\Element)#3 (30) { string(22) "(object value omitted)" ["attributes"]=> string(22) "(object value omitted)" + ["children"]=> + string(22) "(object value omitted)" ["firstElementChild"]=> NULL ["lastElementChild"]=> @@ -75,7 +77,7 @@ object(Dom\Element)#3 (30) { ["textContent"]=> string(0) "" } -object(Dom\Element)#4 (30) { +object(Dom\Element)#4 (31) { ["namespaceURI"]=> string(12) "urn:example2" ["prefix"]=> @@ -92,6 +94,8 @@ object(Dom\Element)#4 (30) { string(22) "(object value omitted)" ["attributes"]=> string(22) "(object value omitted)" + ["children"]=> + string(22) "(object value omitted)" ["firstElementChild"]=> NULL ["lastElementChild"]=> diff --git a/ext/dom/tests/modern/common/ParentNode_children.phpt b/ext/dom/tests/modern/common/ParentNode_children.phpt new file mode 100644 index 0000000000000..54db132f1b161 --- /dev/null +++ b/ext/dom/tests/modern/common/ParentNode_children.phpt @@ -0,0 +1,48 @@ +--TEST-- +ParentNode::$children +--EXTENSIONS-- +dom +--FILE-- + + + + + + + +XML); +$children = $dom->documentElement->children; +var_dump($children === $dom->documentElement->children); // Tests caching behaviour +var_dump($children !== (clone $dom->documentElement)->children); // Tests caching behaviour does not persist across clones +var_dump(count($children)); +var_dump($children->length); + +foreach ($children as $key => $child) { + var_dump($key, $child->nodeName); +} + +foreach ($children->namedItem('foo')->children as $key => $child) { + var_dump($key, $child->nodeName); +} + +?> +--EXPECT-- +bool(true) +bool(true) +int(4) +int(4) +int(0) +string(1) "a" +int(1) +string(1) "b" +int(2) +string(1) "c" +int(3) +string(1) "e" +int(0) +string(2) "c1" +int(1) +string(2) "c2" diff --git a/ext/dom/tests/modern/html/interactions/HTMLDocument_should_retain_properties_and_owner_01.phpt b/ext/dom/tests/modern/html/interactions/HTMLDocument_should_retain_properties_and_owner_01.phpt index 5051c3f9aabf6..c6347ae485894 100644 --- a/ext/dom/tests/modern/html/interactions/HTMLDocument_should_retain_properties_and_owner_01.phpt +++ b/ext/dom/tests/modern/html/interactions/HTMLDocument_should_retain_properties_and_owner_01.phpt @@ -23,7 +23,7 @@ var_dump(get_class($dom->getElementsByTagName("p")->item(0))); ?> --EXPECT-- -object(Dom\HTMLDocument)#1 (28) { +object(Dom\HTMLDocument)#1 (29) { ["implementation"]=> string(22) "(object value omitted)" ["URL"]=> @@ -40,6 +40,8 @@ object(Dom\HTMLDocument)#1 (28) { NULL ["documentElement"]=> string(22) "(object value omitted)" + ["children"]=> + string(22) "(object value omitted)" ["firstElementChild"]=> string(22) "(object value omitted)" ["lastElementChild"]=> diff --git a/ext/dom/tests/modern/html/interactions/HTMLDocument_should_retain_properties_and_owner_02.phpt b/ext/dom/tests/modern/html/interactions/HTMLDocument_should_retain_properties_and_owner_02.phpt index b160c72f0a54f..d7dea308b5d2a 100644 --- a/ext/dom/tests/modern/html/interactions/HTMLDocument_should_retain_properties_and_owner_02.phpt +++ b/ext/dom/tests/modern/html/interactions/HTMLDocument_should_retain_properties_and_owner_02.phpt @@ -23,7 +23,7 @@ var_dump(get_class($dom->getElementsByTagName("p")->item(0))); ?> --EXPECT-- -object(Dom\HTMLDocument)#1 (28) { +object(Dom\HTMLDocument)#1 (29) { ["implementation"]=> string(22) "(object value omitted)" ["URL"]=> @@ -40,6 +40,8 @@ object(Dom\HTMLDocument)#1 (28) { NULL ["documentElement"]=> string(22) "(object value omitted)" + ["children"]=> + string(22) "(object value omitted)" ["firstElementChild"]=> string(22) "(object value omitted)" ["lastElementChild"]=> diff --git a/ext/dom/tests/modern/spec/Document_implementation_createDocument.phpt b/ext/dom/tests/modern/spec/Document_implementation_createDocument.phpt index ae49a6a494c9a..4cf1b3888feed 100644 --- a/ext/dom/tests/modern/spec/Document_implementation_createDocument.phpt +++ b/ext/dom/tests/modern/spec/Document_implementation_createDocument.phpt @@ -37,7 +37,7 @@ echo $dom->implementation->createDocument(null, "", $dtd)->saveXml(), "\n"; ?> --EXPECT-- --- (null, "") --- -object(Dom\XMLDocument)#3 (32) { +object(Dom\XMLDocument)#3 (33) { ["xmlEncoding"]=> string(5) "UTF-8" ["xmlStandalone"]=> @@ -62,6 +62,8 @@ object(Dom\XMLDocument)#3 (32) { NULL ["documentElement"]=> NULL + ["children"]=> + string(22) "(object value omitted)" ["firstElementChild"]=> NULL ["lastElementChild"]=> diff --git a/ext/dom/tests/modern/spec/ParentNode_append_exception_consistency.phpt b/ext/dom/tests/modern/spec/ParentNode_append_exception_consistency.phpt index 67a964a7ec515..a88b4fc808b08 100644 --- a/ext/dom/tests/modern/spec/ParentNode_append_exception_consistency.phpt +++ b/ext/dom/tests/modern/spec/ParentNode_append_exception_consistency.phpt @@ -18,7 +18,9 @@ var_dump($element->parentNode); ?> --EXPECT-- Exception: Cannot have more than one element child in a document -object(Dom\DocumentFragment)#2 (17) { +object(Dom\DocumentFragment)#2 (18) { + ["children"]=> + string(22) "(object value omitted)" ["firstElementChild"]=> string(22) "(object value omitted)" ["lastElementChild"]=> diff --git a/ext/dom/tests/modern/xml/XMLDocument_debug.phpt b/ext/dom/tests/modern/xml/XMLDocument_debug.phpt index e2d6ebffe89cd..7067e5607bdb6 100644 --- a/ext/dom/tests/modern/xml/XMLDocument_debug.phpt +++ b/ext/dom/tests/modern/xml/XMLDocument_debug.phpt @@ -10,7 +10,7 @@ var_dump($dom); ?> --EXPECT-- -object(Dom\XMLDocument)#1 (32) { +object(Dom\XMLDocument)#1 (33) { ["xmlEncoding"]=> string(5) "UTF-8" ["xmlStandalone"]=> @@ -35,6 +35,8 @@ object(Dom\XMLDocument)#1 (32) { NULL ["documentElement"]=> NULL + ["children"]=> + string(22) "(object value omitted)" ["firstElementChild"]=> NULL ["lastElementChild"]=> diff --git a/ext/dom/tests/modern/xml/XMLDocument_fromEmptyDocument_02.phpt b/ext/dom/tests/modern/xml/XMLDocument_fromEmptyDocument_02.phpt index 62d64a05f9b2a..6276d1e9a98cb 100644 --- a/ext/dom/tests/modern/xml/XMLDocument_fromEmptyDocument_02.phpt +++ b/ext/dom/tests/modern/xml/XMLDocument_fromEmptyDocument_02.phpt @@ -10,7 +10,7 @@ var_dump($dom); ?> --EXPECT-- -object(Dom\XMLDocument)#1 (32) { +object(Dom\XMLDocument)#1 (33) { ["xmlEncoding"]=> string(5) "UTF-8" ["xmlStandalone"]=> @@ -35,6 +35,8 @@ object(Dom\XMLDocument)#1 (32) { NULL ["documentElement"]=> NULL + ["children"]=> + string(22) "(object value omitted)" ["firstElementChild"]=> NULL ["lastElementChild"]=> diff --git a/ext/dom/tests/modern/xml/XMLDocument_node_ownerDocument_for_XML.phpt b/ext/dom/tests/modern/xml/XMLDocument_node_ownerDocument_for_XML.phpt index e18c43f05ae82..89cfe83de710f 100644 --- a/ext/dom/tests/modern/xml/XMLDocument_node_ownerDocument_for_XML.phpt +++ b/ext/dom/tests/modern/xml/XMLDocument_node_ownerDocument_for_XML.phpt @@ -13,7 +13,7 @@ var_dump($element->ownerDocument); ?> --EXPECTF-- -object(Dom\XMLDocument)#1 (32) { +object(Dom\XMLDocument)#1 (33) { ["xmlEncoding"]=> string(5) "UTF-8" ["xmlStandalone"]=> @@ -38,6 +38,8 @@ object(Dom\XMLDocument)#1 (32) { NULL ["documentElement"]=> string(22) "(object value omitted)" + ["children"]=> + string(22) "(object value omitted)" ["firstElementChild"]=> string(22) "(object value omitted)" ["lastElementChild"]=> diff --git a/ext/dom/tests/modern/xml/gh18979.phpt b/ext/dom/tests/modern/xml/gh18979.phpt new file mode 100644 index 0000000000000..3a90bd583773b --- /dev/null +++ b/ext/dom/tests/modern/xml/gh18979.phpt @@ -0,0 +1,13 @@ +--TEST-- +GH-18979 (DOM\XMLDocument::createComment() triggers undefined behavior with null byte) +--EXTENSIONS-- +dom +--FILE-- +createElement("container"); +$container->append($dom->createComment("\0")); +var_dump($container->innerHTML); +?> +--EXPECT-- +string(7) "" diff --git a/ext/dom/xml_serializer.c b/ext/dom/xml_serializer.c index debbb41fdadeb..a4b46082b0ee5 100644 --- a/ext/dom/xml_serializer.c +++ b/ext/dom/xml_serializer.c @@ -640,7 +640,11 @@ static int dom_xml_serialize_comment_node(xmlOutputBufferPtr out, xmlNodePtr com const xmlChar *ptr = comment->content; if (ptr != NULL) { TRY(dom_xml_check_char_production(ptr)); - if (strstr((const char *) ptr, "--") != NULL || ptr[strlen((const char *) ptr) - 1] == '-') { + if (strstr((const char *) ptr, "--") != NULL) { + return -1; + } + size_t len = strlen((const char *) ptr); + if (len > 0 && ptr[len - 1] == '-') { return -1; } } diff --git a/ext/enchant/enchant.stub.php b/ext/enchant/enchant.stub.php index eafce22eac7d3..6ddbee768f14d 100644 --- a/ext/enchant/enchant.stub.php +++ b/ext/enchant/enchant.stub.php @@ -5,14 +5,14 @@ /** * @var int * @cvalue PHP_ENCHANT_MYSPELL - * @deprecated */ +#[\Deprecated(since: '8.0', message: 'as enchant_broker_get_dict_path() and enchant_broker_set_dict_path() are deprecated')] const ENCHANT_MYSPELL = UNKNOWN; /** * @var int * @cvalue PHP_ENCHANT_ISPELL - * @deprecated */ +#[\Deprecated(since: '8.0', message: 'as enchant_broker_get_dict_path() and enchant_broker_set_dict_path() are deprecated')] const ENCHANT_ISPELL = UNKNOWN; #ifdef HAVE_ENCHANT_GET_VERSION /** diff --git a/ext/enchant/enchant_arginfo.h b/ext/enchant/enchant_arginfo.h index a06f713f9cedf..0cd8707e1a172 100644 --- a/ext/enchant/enchant_arginfo.h +++ b/ext/enchant/enchant_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 9dd3fce23840ced1c265f8ec1dd3929298fdfe37 */ + * Stub hash: 31974eb901477da53ede7476953d461d32f772ba */ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_enchant_broker_init, 0, 0, EnchantBroker, MAY_BE_FALSE) ZEND_END_ARG_INFO() @@ -224,6 +224,32 @@ static void register_enchant_symbols(int module_number) 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); attribute_Deprecated_func_enchant_dict_is_in_session_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + zend_constant *const_ENCHANT_MYSPELL = zend_hash_str_find_ptr(EG(zend_constants), "ENCHANT_MYSPELL", sizeof("ENCHANT_MYSPELL") - 1); + + zend_attribute *attribute_Deprecated_const_ENCHANT_MYSPELL_0 = zend_add_global_constant_attribute(const_ENCHANT_MYSPELL, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + zval attribute_Deprecated_const_ENCHANT_MYSPELL_0_arg0; + zend_string *attribute_Deprecated_const_ENCHANT_MYSPELL_0_arg0_str = zend_string_init("8.0", strlen("8.0"), 1); + ZVAL_STR(&attribute_Deprecated_const_ENCHANT_MYSPELL_0_arg0, attribute_Deprecated_const_ENCHANT_MYSPELL_0_arg0_str); + ZVAL_COPY_VALUE(&attribute_Deprecated_const_ENCHANT_MYSPELL_0->args[0].value, &attribute_Deprecated_const_ENCHANT_MYSPELL_0_arg0); + 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); + attribute_Deprecated_const_ENCHANT_MYSPELL_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + zend_constant *const_ENCHANT_ISPELL = zend_hash_str_find_ptr(EG(zend_constants), "ENCHANT_ISPELL", sizeof("ENCHANT_ISPELL") - 1); + + zend_attribute *attribute_Deprecated_const_ENCHANT_ISPELL_0 = zend_add_global_constant_attribute(const_ENCHANT_ISPELL, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + zval attribute_Deprecated_const_ENCHANT_ISPELL_0_arg0; + zend_string *attribute_Deprecated_const_ENCHANT_ISPELL_0_arg0_str = zend_string_init("8.0", strlen("8.0"), 1); + ZVAL_STR(&attribute_Deprecated_const_ENCHANT_ISPELL_0_arg0, attribute_Deprecated_const_ENCHANT_ISPELL_0_arg0_str); + ZVAL_COPY_VALUE(&attribute_Deprecated_const_ENCHANT_ISPELL_0->args[0].value, &attribute_Deprecated_const_ENCHANT_ISPELL_0_arg0); + 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); + attribute_Deprecated_const_ENCHANT_ISPELL_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); } static zend_class_entry *register_class_EnchantBroker(void) diff --git a/ext/filter/filter.c b/ext/filter/filter.c index 50eefb440d67a..7f3624eb4c07a 100644 --- a/ext/filter/filter.c +++ b/ext/filter/filter.c @@ -27,6 +27,7 @@ ZEND_DECLARE_MODULE_GLOBALS(filter) +#include "zend_attributes.h" #include "filter_private.h" #include "filter_arginfo.h" diff --git a/ext/filter/filter.stub.php b/ext/filter/filter.stub.php index 030de50f51890..a8790bb7cd615 100644 --- a/ext/filter/filter.stub.php +++ b/ext/filter/filter.stub.php @@ -121,14 +121,14 @@ /** * @var int * @cvalue FILTER_SANITIZE_STRING - * @deprecated */ +#[\Deprecated(since: '8.1', message: 'use htmlspecialchars() instead')] const FILTER_SANITIZE_STRING = UNKNOWN; /** * @var int * @cvalue FILTER_SANITIZE_STRING - * @deprecated */ +#[\Deprecated(since: '8.1', message: 'use htmlspecialchars() instead')] const FILTER_SANITIZE_STRIPPED = UNKNOWN; /** * @var int diff --git a/ext/filter/filter_arginfo.h b/ext/filter/filter_arginfo.h index a05806c5e1201..8cc562e5de236 100644 --- a/ext/filter/filter_arginfo.h +++ b/ext/filter/filter_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: c3f3240137eaa89316276920acf35f975b2dd8f9 */ + * Stub hash: a0f9a546d59bb27854af79a92e353f118ca6bdaf */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_filter_has_var, 0, 2, _IS_BOOL, 0) ZEND_ARG_TYPE_INFO(0, input_type, IS_LONG, 0) @@ -114,4 +114,31 @@ static void register_filter_symbols(int module_number) REGISTER_LONG_CONSTANT("FILTER_FLAG_GLOBAL_RANGE", FILTER_FLAG_GLOBAL_RANGE, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("FILTER_FLAG_HOSTNAME", FILTER_FLAG_HOSTNAME, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("FILTER_FLAG_EMAIL_UNICODE", FILTER_FLAG_EMAIL_UNICODE, CONST_PERSISTENT); + + zend_constant *const_FILTER_SANITIZE_STRING = zend_hash_str_find_ptr(EG(zend_constants), "FILTER_SANITIZE_STRING", sizeof("FILTER_SANITIZE_STRING") - 1); + + 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 attribute_Deprecated_const_FILTER_SANITIZE_STRING_0_arg0; + zend_string *attribute_Deprecated_const_FILTER_SANITIZE_STRING_0_arg0_str = zend_string_init("8.1", strlen("8.1"), 1); + ZVAL_STR(&attribute_Deprecated_const_FILTER_SANITIZE_STRING_0_arg0, attribute_Deprecated_const_FILTER_SANITIZE_STRING_0_arg0_str); + ZVAL_COPY_VALUE(&attribute_Deprecated_const_FILTER_SANITIZE_STRING_0->args[0].value, &attribute_Deprecated_const_FILTER_SANITIZE_STRING_0_arg0); + 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); + attribute_Deprecated_const_FILTER_SANITIZE_STRING_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + zend_constant *const_FILTER_SANITIZE_STRIPPED = zend_hash_str_find_ptr(EG(zend_constants), "FILTER_SANITIZE_STRIPPED", sizeof("FILTER_SANITIZE_STRIPPED") - 1); + + 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 attribute_Deprecated_const_FILTER_SANITIZE_STRIPPED_0_arg0; + zend_string *attribute_Deprecated_const_FILTER_SANITIZE_STRIPPED_0_arg0_str = zend_string_init("8.1", strlen("8.1"), 1); + ZVAL_STR(&attribute_Deprecated_const_FILTER_SANITIZE_STRIPPED_0_arg0, attribute_Deprecated_const_FILTER_SANITIZE_STRIPPED_0_arg0_str); + ZVAL_COPY_VALUE(&attribute_Deprecated_const_FILTER_SANITIZE_STRIPPED_0->args[0].value, &attribute_Deprecated_const_FILTER_SANITIZE_STRIPPED_0_arg0); + 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); + attribute_Deprecated_const_FILTER_SANITIZE_STRIPPED_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); } diff --git a/ext/filter/tests/025.phpt b/ext/filter/tests/025.phpt index d8e06e3ac20cc..05459fcb1cb27 100644 --- a/ext/filter/tests/025.phpt +++ b/ext/filter/tests/025.phpt @@ -16,24 +16,24 @@ var_dump(filter_var(".", FILTER_SANITIZE_STRING)); echo "Done\n"; ?> --EXPECTF-- -Deprecated: Constant FILTER_SANITIZE_STRING is deprecated in %s on line %d +Deprecated: Constant FILTER_SANITIZE_STRING is deprecated since 8.1, use htmlspecialchars() instead in %s on line %d string(0) "" -Deprecated: Constant FILTER_SANITIZE_STRING is deprecated in %s on line %d +Deprecated: Constant FILTER_SANITIZE_STRING is deprecated since 8.1, use htmlspecialchars() instead in %s on line %d string(0) "" -Deprecated: Constant FILTER_SANITIZE_STRING is deprecated in %s on line %d +Deprecated: Constant FILTER_SANITIZE_STRING is deprecated since 8.1, use htmlspecialchars() instead in %s on line %d string(12) "!@#$%^&*()'"" -Deprecated: Constant FILTER_SANITIZE_STRING is deprecated in %s on line %d +Deprecated: Constant FILTER_SANITIZE_STRING is deprecated since 8.1, use htmlspecialchars() instead in %s on line %d string(24) "!@#$%^&*()'"" -Deprecated: Constant FILTER_SANITIZE_STRING is deprecated in %s on line %d +Deprecated: Constant FILTER_SANITIZE_STRING is deprecated since 8.1, use htmlspecialchars() instead in %s on line %d string(11) "`1234567890" -Deprecated: Constant FILTER_SANITIZE_STRING is deprecated in %s on line %d +Deprecated: Constant FILTER_SANITIZE_STRING is deprecated since 8.1, use htmlspecialchars() instead in %s on line %d string(5) "`123`" -Deprecated: Constant FILTER_SANITIZE_STRING is deprecated in %s on line %d +Deprecated: Constant FILTER_SANITIZE_STRING is deprecated since 8.1, use htmlspecialchars() instead in %s on line %d string(1) "." Done diff --git a/ext/filter/tests/026.phpt b/ext/filter/tests/026.phpt index db43df7949a0d..856f5325cb3b9 100644 --- a/ext/filter/tests/026.phpt +++ b/ext/filter/tests/026.phpt @@ -20,30 +20,30 @@ var_dump(filter_var("", FILTER_SANITIZE_STRIPPED, FILTER_FLAG_STRIP_HIGH)); echo "Done\n"; ?> --EXPECTF-- -Deprecated: Constant FILTER_SANITIZE_STRIPPED is deprecated in %s on line %d +Deprecated: Constant FILTER_SANITIZE_STRIPPED is deprecated since 8.1, use htmlspecialchars() instead in %s on line %d string(40) "Let me see you Stripped down to the bone" -Deprecated: Constant FILTER_SANITIZE_STRIPPED is deprecated in %s on line %d +Deprecated: Constant FILTER_SANITIZE_STRIPPED is deprecated since 8.1, use htmlspecialchars() instead in %s on line %d string(11) "!@#$%^&*()>" -Deprecated: Constant FILTER_SANITIZE_STRIPPED is deprecated in %s on line %d +Deprecated: Constant FILTER_SANITIZE_STRIPPED is deprecated since 8.1, use htmlspecialchars() instead in %s on line %d string(0) "" -Deprecated: Constant FILTER_SANITIZE_STRIPPED is deprecated in %s on line %d +Deprecated: Constant FILTER_SANITIZE_STRIPPED is deprecated since 8.1, use htmlspecialchars() instead in %s on line %d string(40) "Let me see you Stripped down to the bone" -Deprecated: Constant FILTER_SANITIZE_STRIPPED is deprecated in %s on line %d +Deprecated: Constant FILTER_SANITIZE_STRIPPED is deprecated since 8.1, use htmlspecialchars() instead in %s on line %d string(11) "!@#$%^&*()>" -Deprecated: Constant FILTER_SANITIZE_STRIPPED is deprecated in %s on line %d +Deprecated: Constant FILTER_SANITIZE_STRIPPED is deprecated since 8.1, use htmlspecialchars() instead in %s on line %d string(0) "" -Deprecated: Constant FILTER_SANITIZE_STRIPPED is deprecated in %s on line %d +Deprecated: Constant FILTER_SANITIZE_STRIPPED is deprecated since 8.1, use htmlspecialchars() instead in %s on line %d string(40) "Let me see you Stripped down to the bone" -Deprecated: Constant FILTER_SANITIZE_STRIPPED is deprecated in %s on line %d +Deprecated: Constant FILTER_SANITIZE_STRIPPED is deprecated since 8.1, use htmlspecialchars() instead in %s on line %d string(11) "!@#$%^&*()>" -Deprecated: Constant FILTER_SANITIZE_STRIPPED is deprecated in %s on line %d +Deprecated: Constant FILTER_SANITIZE_STRIPPED is deprecated since 8.1, use htmlspecialchars() instead in %s on line %d string(0) "" Done diff --git a/ext/filter/tests/042.phpt b/ext/filter/tests/042.phpt index 0795392f7acaa..28f346afeefc4 100644 --- a/ext/filter/tests/042.phpt +++ b/ext/filter/tests/042.phpt @@ -15,8 +15,8 @@ $a = filter_var($var, FILTER_SANITIZE_STRING, array("flags" => FILTER_FLAG_STRIP echo $a . "\n"; ?> --EXPECTF-- -Deprecated: Constant FILTER_SANITIZE_STRING is deprecated in %s on line %d +Deprecated: Constant FILTER_SANITIZE_STRING is deprecated since 8.1, use htmlspecialchars() instead in %s on line %d XYZalert(/ext/filter+bypass/);ABC -Deprecated: Constant FILTER_SANITIZE_STRING is deprecated in %s on line %d +Deprecated: Constant FILTER_SANITIZE_STRING is deprecated since 8.1, use htmlspecialchars() instead in %s on line %d XYZalert(/ext/filter+bypass/);ABC diff --git a/ext/filter/tests/bug69203.phpt b/ext/filter/tests/bug69203.phpt index 3453c7c0adc6f..85356ba2a1349 100644 --- a/ext/filter/tests/bug69203.phpt +++ b/ext/filter/tests/bug69203.phpt @@ -10,7 +10,7 @@ var_dump(filter_var("\x7f", FILTER_SANITIZE_ENCODED, FILTER_FLAG_STRIP_HIGH)); var_dump(filter_var("\x7f", FILTER_SANITIZE_SPECIAL_CHARS, FILTER_FLAG_STRIP_HIGH)); ?> --EXPECTF-- -Deprecated: Constant FILTER_SANITIZE_STRING is deprecated in %s on line %d +Deprecated: Constant FILTER_SANITIZE_STRING is deprecated since 8.1, use htmlspecialchars() instead in %s on line %d string(0) "" string(0) "" string(0) "" diff --git a/ext/intl/collator/collator_sort.c b/ext/intl/collator/collator_sort.c index 75466aacb07af..ee68a21c98960 100644 --- a/ext/intl/collator/collator_sort.c +++ b/ext/intl/collator/collator_sort.c @@ -24,10 +24,6 @@ #include "collator_convert.h" #include "intl_convert.h" -#if !defined(HAVE_PTRDIFF_T) && !defined(_PTRDIFF_T_DEFINED) -typedef zend_long ptrdiff_t; -#endif - /** * Declare 'index' which will point to sort key in sort key * buffer. diff --git a/ext/intl/formatter/formatter_format.c b/ext/intl/formatter/formatter_format.c index 0323757ed8620..54c5d92fe18a1 100644 --- a/ext/intl/formatter/formatter_format.c +++ b/ext/intl/formatter/formatter_format.c @@ -104,7 +104,7 @@ PHP_FUNCTION( numfmt_format ) INTL_METHOD_CHECK_STATUS( nfo, "Number formatting failed" ); break; case FORMAT_TYPE_CURRENCY: - if (getThis()) { + if (hasThis()) { const char *space; const char *class_name = get_active_class_name(&space); zend_argument_value_error(2, "cannot be NumberFormatter::TYPE_CURRENCY constant, " diff --git a/ext/intl/formatter/formatter_parse.c b/ext/intl/formatter/formatter_parse.c index 9939900650408..ba8307419b4cf 100644 --- a/ext/intl/formatter/formatter_parse.c +++ b/ext/intl/formatter/formatter_parse.c @@ -86,7 +86,7 @@ PHP_FUNCTION( numfmt_parse ) RETVAL_DOUBLE(val_double); break; case FORMAT_TYPE_CURRENCY: - if (getThis()) { + if (hasThis()) { const char *space; const char *class_name = get_active_class_name(&space); zend_argument_value_error(2, "cannot be NumberFormatter::TYPE_CURRENCY constant, " diff --git a/ext/intl/listformatter/listformatter_class.c b/ext/intl/listformatter/listformatter_class.c index 1fe8da554a1ca..f1a5039079b8a 100644 --- a/ext/intl/listformatter/listformatter_class.c +++ b/ext/intl/listformatter/listformatter_class.c @@ -135,9 +135,9 @@ PHP_METHOD(IntlListFormatter, format) zval *val; ZEND_HASH_FOREACH_VAL(ht, val) { - zend_string *str_val; + zend_string *str_val, *tmp_str; - str_val = zval_get_string(val); + str_val = zval_get_tmp_string(val, &tmp_str); // Convert PHP string to UTF-16 UChar *ustr = NULL; @@ -145,7 +145,7 @@ PHP_METHOD(IntlListFormatter, format) UErrorCode status = U_ZERO_ERROR; intl_convert_utf8_to_utf16(&ustr, &ustr_len, ZSTR_VAL(str_val), ZSTR_LEN(str_val), &status); - zend_string_release(str_val); + zend_tmp_string_release(tmp_str); if (U_FAILURE(status)) { // We can't use goto cleanup because items and itemLengths are incompletely allocated diff --git a/ext/ldap/config.m4 b/ext/ldap/config.m4 index 7d0229f6868c4..ae0ae7fba9598 100644 --- a/ext/ldap/config.m4 +++ b/ext/ldap/config.m4 @@ -60,15 +60,20 @@ if test "$PHP_LDAP" != "no"; then [-DZEND_ENABLE_STATIC_TSRMLS_CACHE=1]) AS_VAR_IF([PHP_LDAP], [yes], [ - PKG_CHECK_MODULES([LDAP], [lber ldap]) - PHP_LDAP_PKGCONFIG=true - ], [PHP_LDAP_CHECKS([$PHP_LDAP])]) + PKG_CHECK_MODULES([LDAP], [lber ldap], + PHP_LDAP_PKGCONFIG=true, PHP_LDAP_PKGCONFIG=false)]) AS_IF([test "$PHP_LDAP_PKGCONFIG" = true], [ PHP_EVAL_INCLINE([$LDAP_CFLAGS]) PHP_EVAL_LIBLINE([$LDAP_LIBS], [LDAP_SHARED_LIBADD]) ], [ - AS_VAR_IF([LDAP_DIR],, [AC_MSG_ERROR([Cannot find ldap.h])]) + AS_VAR_IF([PHP_LDAP], [yes], [ + for i in /usr/local /usr; do + PHP_LDAP_CHECKS([$i]) + done + ], [PHP_LDAP_CHECKS([$PHP_LDAP])]) + AC_MSG_CHECKING([for ldap.h]) + AS_VAR_IF([LDAP_DIR],, [AC_MSG_ERROR([Cannot find ldap.h])], AC_MSG_RESULT([$LDAP_DIR])) dnl -pc removal is a hack for clang MACHINE_INCLUDES=$($CC -dumpmachine | $SED 's/-pc//') diff --git a/ext/mysqli/mysqli.stub.php b/ext/mysqli/mysqli.stub.php index de287b347deef..06db6ac26860b 100644 --- a/ext/mysqli/mysqli.stub.php +++ b/ext/mysqli/mysqli.stub.php @@ -136,8 +136,8 @@ /** * @var int * @cvalue MYSQLI_STORE_RESULT_COPY_DATA - * @deprecated */ +#[\Deprecated(since: '8.4', message: 'as the mysqli_store_result() parameter is unused since 8.1')] const MYSQLI_STORE_RESULT_COPY_DATA = UNKNOWN; /* for mysqli_fetch_assoc */ @@ -423,14 +423,14 @@ /** * @var int * @cvalue MYSQL_NO_DATA - * @deprecated */ +#[\Deprecated(since: '8.1', message: 'as it was unused')] const MYSQLI_NO_DATA = UNKNOWN; /** * @var int * @cvalue MYSQL_DATA_TRUNCATED - * @deprecated */ +#[\Deprecated(since: '8.1', message: 'as it was unused')] const MYSQLI_DATA_TRUNCATED = UNKNOWN; /* reporting */ @@ -469,87 +469,87 @@ /** * @var int * @cvalue SERVER_QUERY_NO_GOOD_INDEX_USED - * @deprecated */ +#[\Deprecated(since: '8.1', message: 'as it was unused')] const MYSQLI_SERVER_QUERY_NO_GOOD_INDEX_USED = UNKNOWN; /** * @var int * @cvalue SERVER_QUERY_NO_INDEX_USED - * @deprecated */ +#[\Deprecated(since: '8.1', message: 'as it was unused')] const MYSQLI_SERVER_QUERY_NO_INDEX_USED = UNKNOWN; /** * @var int * @cvalue SERVER_QUERY_WAS_SLOW - * @deprecated */ +#[\Deprecated(since: '8.1', message: 'as it was unused')] const MYSQLI_SERVER_QUERY_WAS_SLOW = UNKNOWN; /** * @var int * @cvalue SERVER_PS_OUT_PARAMS - * @deprecated */ +#[\Deprecated(since: '8.1', message: 'as it was unused')] const MYSQLI_SERVER_PS_OUT_PARAMS = UNKNOWN; /** * @var int * @cvalue REFRESH_GRANT - * @deprecated */ +#[\Deprecated(since: '8.4', message: 'as mysqli_refresh() is deprecated')] const MYSQLI_REFRESH_GRANT = UNKNOWN; /** * @var int * @cvalue REFRESH_LOG - * @deprecated */ +#[\Deprecated(since: '8.4', message: 'as mysqli_refresh() is deprecated')] const MYSQLI_REFRESH_LOG = UNKNOWN; /** * @var int * @cvalue REFRESH_TABLES - * @deprecated */ +#[\Deprecated(since: '8.4', message: 'as mysqli_refresh() is deprecated')] const MYSQLI_REFRESH_TABLES = UNKNOWN; /** * @var int * @cvalue REFRESH_HOSTS - * @deprecated */ +#[\Deprecated(since: '8.4', message: 'as mysqli_refresh() is deprecated')] const MYSQLI_REFRESH_HOSTS = UNKNOWN; /** * @var int * @cvalue REFRESH_STATUS - * @deprecated */ +#[\Deprecated(since: '8.4', message: 'as mysqli_refresh() is deprecated')] const MYSQLI_REFRESH_STATUS = UNKNOWN; /** * @var int * @cvalue REFRESH_THREADS - * @deprecated */ +#[\Deprecated(since: '8.4', message: 'as mysqli_refresh() is deprecated')] const MYSQLI_REFRESH_THREADS = UNKNOWN; /** * @var int * @cvalue REFRESH_SLAVE - * @deprecated */ +#[\Deprecated(since: '8.4', message: 'as mysqli_refresh() is deprecated')] const MYSQLI_REFRESH_REPLICA = UNKNOWN; /** * @var int * @cvalue REFRESH_SLAVE - * @deprecated */ +#[\Deprecated(since: '8.4', message: 'as mysqli_refresh() is deprecated')] const MYSQLI_REFRESH_SLAVE = UNKNOWN; /** * @var int * @cvalue REFRESH_MASTER - * @deprecated */ +#[\Deprecated(since: '8.4', message: 'as mysqli_refresh() is deprecated')] const MYSQLI_REFRESH_MASTER = UNKNOWN; /** * @var int * @cvalue REFRESH_BACKUP_LOG - * @deprecated */ +#[\Deprecated(since: '8.4', message: 'as mysqli_refresh() is deprecated')] const MYSQLI_REFRESH_BACKUP_LOG = UNKNOWN; /** @@ -591,8 +591,8 @@ /** * @var bool - * @deprecated */ +#[\Deprecated(since: '8.2', message: 'as it is always false')] const MYSQLI_IS_MARIADB = false; final class mysqli_driver diff --git a/ext/mysqli/mysqli_api.c b/ext/mysqli/mysqli_api.c index 5e2645740b26e..2a20919eee45e 100644 --- a/ext/mysqli/mysqli_api.c +++ b/ext/mysqli/mysqli_api.c @@ -327,7 +327,7 @@ PHP_FUNCTION(mysqli_data_seek) MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, mysql_result, "mysqli_result", MYSQLI_STATUS_VALID); if (mysqli_result_is_unbuffered(result)) { - if (getThis()) { + if (hasThis()) { zend_throw_error(NULL, "mysqli_result::data_seek() cannot be used in MYSQLI_USE_RESULT mode"); } else { zend_throw_error(NULL, "mysqli_data_seek() cannot be used in MYSQLI_USE_RESULT mode"); @@ -855,7 +855,7 @@ PHP_FUNCTION(mysqli_free_result) /* {{{ Get MySQL client info */ PHP_FUNCTION(mysqli_get_client_info) { - if (getThis()) { + if (hasThis()) { if (zend_parse_parameters_none() == FAILURE) { RETURN_THROWS(); } diff --git a/ext/mysqli/mysqli_arginfo.h b/ext/mysqli/mysqli_arginfo.h index 4e624d623d807..43dba58417f36 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: 32baf7b0642af68dea551687bc44ae47d708d810 */ + * Stub hash: 2547f63fd024fd5f4fecc574bbcff1301d1d36e5 */ 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) @@ -1187,6 +1187,240 @@ static void register_mysqli_symbols(int module_number) 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); attribute_Deprecated_func_mysqli_refresh_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + zend_constant *const_MYSQLI_STORE_RESULT_COPY_DATA = zend_hash_str_find_ptr(EG(zend_constants), "MYSQLI_STORE_RESULT_COPY_DATA", sizeof("MYSQLI_STORE_RESULT_COPY_DATA") - 1); + + 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 attribute_Deprecated_const_MYSQLI_STORE_RESULT_COPY_DATA_0_arg0; + zend_string *attribute_Deprecated_const_MYSQLI_STORE_RESULT_COPY_DATA_0_arg0_str = zend_string_init("8.4", strlen("8.4"), 1); + ZVAL_STR(&attribute_Deprecated_const_MYSQLI_STORE_RESULT_COPY_DATA_0_arg0, attribute_Deprecated_const_MYSQLI_STORE_RESULT_COPY_DATA_0_arg0_str); + ZVAL_COPY_VALUE(&attribute_Deprecated_const_MYSQLI_STORE_RESULT_COPY_DATA_0->args[0].value, &attribute_Deprecated_const_MYSQLI_STORE_RESULT_COPY_DATA_0_arg0); + 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); + attribute_Deprecated_const_MYSQLI_STORE_RESULT_COPY_DATA_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + zend_constant *const_MYSQLI_NO_DATA = zend_hash_str_find_ptr(EG(zend_constants), "MYSQLI_NO_DATA", sizeof("MYSQLI_NO_DATA") - 1); + + 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 attribute_Deprecated_const_MYSQLI_NO_DATA_0_arg0; + zend_string *attribute_Deprecated_const_MYSQLI_NO_DATA_0_arg0_str = zend_string_init("8.1", strlen("8.1"), 1); + ZVAL_STR(&attribute_Deprecated_const_MYSQLI_NO_DATA_0_arg0, attribute_Deprecated_const_MYSQLI_NO_DATA_0_arg0_str); + ZVAL_COPY_VALUE(&attribute_Deprecated_const_MYSQLI_NO_DATA_0->args[0].value, &attribute_Deprecated_const_MYSQLI_NO_DATA_0_arg0); + 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); + attribute_Deprecated_const_MYSQLI_NO_DATA_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + zend_constant *const_MYSQLI_DATA_TRUNCATED = zend_hash_str_find_ptr(EG(zend_constants), "MYSQLI_DATA_TRUNCATED", sizeof("MYSQLI_DATA_TRUNCATED") - 1); + + 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 attribute_Deprecated_const_MYSQLI_DATA_TRUNCATED_0_arg0; + zend_string *attribute_Deprecated_const_MYSQLI_DATA_TRUNCATED_0_arg0_str = zend_string_init("8.1", strlen("8.1"), 1); + ZVAL_STR(&attribute_Deprecated_const_MYSQLI_DATA_TRUNCATED_0_arg0, attribute_Deprecated_const_MYSQLI_DATA_TRUNCATED_0_arg0_str); + ZVAL_COPY_VALUE(&attribute_Deprecated_const_MYSQLI_DATA_TRUNCATED_0->args[0].value, &attribute_Deprecated_const_MYSQLI_DATA_TRUNCATED_0_arg0); + 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); + attribute_Deprecated_const_MYSQLI_DATA_TRUNCATED_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + zend_constant *const_MYSQLI_SERVER_QUERY_NO_GOOD_INDEX_USED = zend_hash_str_find_ptr(EG(zend_constants), "MYSQLI_SERVER_QUERY_NO_GOOD_INDEX_USED", sizeof("MYSQLI_SERVER_QUERY_NO_GOOD_INDEX_USED") - 1); + + 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 attribute_Deprecated_const_MYSQLI_SERVER_QUERY_NO_GOOD_INDEX_USED_0_arg0; + zend_string *attribute_Deprecated_const_MYSQLI_SERVER_QUERY_NO_GOOD_INDEX_USED_0_arg0_str = zend_string_init("8.1", strlen("8.1"), 1); + ZVAL_STR(&attribute_Deprecated_const_MYSQLI_SERVER_QUERY_NO_GOOD_INDEX_USED_0_arg0, attribute_Deprecated_const_MYSQLI_SERVER_QUERY_NO_GOOD_INDEX_USED_0_arg0_str); + ZVAL_COPY_VALUE(&attribute_Deprecated_const_MYSQLI_SERVER_QUERY_NO_GOOD_INDEX_USED_0->args[0].value, &attribute_Deprecated_const_MYSQLI_SERVER_QUERY_NO_GOOD_INDEX_USED_0_arg0); + 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); + attribute_Deprecated_const_MYSQLI_SERVER_QUERY_NO_GOOD_INDEX_USED_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + zend_constant *const_MYSQLI_SERVER_QUERY_NO_INDEX_USED = zend_hash_str_find_ptr(EG(zend_constants), "MYSQLI_SERVER_QUERY_NO_INDEX_USED", sizeof("MYSQLI_SERVER_QUERY_NO_INDEX_USED") - 1); + + 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 attribute_Deprecated_const_MYSQLI_SERVER_QUERY_NO_INDEX_USED_0_arg0; + zend_string *attribute_Deprecated_const_MYSQLI_SERVER_QUERY_NO_INDEX_USED_0_arg0_str = zend_string_init("8.1", strlen("8.1"), 1); + ZVAL_STR(&attribute_Deprecated_const_MYSQLI_SERVER_QUERY_NO_INDEX_USED_0_arg0, attribute_Deprecated_const_MYSQLI_SERVER_QUERY_NO_INDEX_USED_0_arg0_str); + ZVAL_COPY_VALUE(&attribute_Deprecated_const_MYSQLI_SERVER_QUERY_NO_INDEX_USED_0->args[0].value, &attribute_Deprecated_const_MYSQLI_SERVER_QUERY_NO_INDEX_USED_0_arg0); + 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); + attribute_Deprecated_const_MYSQLI_SERVER_QUERY_NO_INDEX_USED_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + zend_constant *const_MYSQLI_SERVER_QUERY_WAS_SLOW = zend_hash_str_find_ptr(EG(zend_constants), "MYSQLI_SERVER_QUERY_WAS_SLOW", sizeof("MYSQLI_SERVER_QUERY_WAS_SLOW") - 1); + + 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 attribute_Deprecated_const_MYSQLI_SERVER_QUERY_WAS_SLOW_0_arg0; + zend_string *attribute_Deprecated_const_MYSQLI_SERVER_QUERY_WAS_SLOW_0_arg0_str = zend_string_init("8.1", strlen("8.1"), 1); + ZVAL_STR(&attribute_Deprecated_const_MYSQLI_SERVER_QUERY_WAS_SLOW_0_arg0, attribute_Deprecated_const_MYSQLI_SERVER_QUERY_WAS_SLOW_0_arg0_str); + ZVAL_COPY_VALUE(&attribute_Deprecated_const_MYSQLI_SERVER_QUERY_WAS_SLOW_0->args[0].value, &attribute_Deprecated_const_MYSQLI_SERVER_QUERY_WAS_SLOW_0_arg0); + 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); + attribute_Deprecated_const_MYSQLI_SERVER_QUERY_WAS_SLOW_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + zend_constant *const_MYSQLI_SERVER_PS_OUT_PARAMS = zend_hash_str_find_ptr(EG(zend_constants), "MYSQLI_SERVER_PS_OUT_PARAMS", sizeof("MYSQLI_SERVER_PS_OUT_PARAMS") - 1); + + 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 attribute_Deprecated_const_MYSQLI_SERVER_PS_OUT_PARAMS_0_arg0; + zend_string *attribute_Deprecated_const_MYSQLI_SERVER_PS_OUT_PARAMS_0_arg0_str = zend_string_init("8.1", strlen("8.1"), 1); + ZVAL_STR(&attribute_Deprecated_const_MYSQLI_SERVER_PS_OUT_PARAMS_0_arg0, attribute_Deprecated_const_MYSQLI_SERVER_PS_OUT_PARAMS_0_arg0_str); + ZVAL_COPY_VALUE(&attribute_Deprecated_const_MYSQLI_SERVER_PS_OUT_PARAMS_0->args[0].value, &attribute_Deprecated_const_MYSQLI_SERVER_PS_OUT_PARAMS_0_arg0); + 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); + attribute_Deprecated_const_MYSQLI_SERVER_PS_OUT_PARAMS_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + zend_constant *const_MYSQLI_REFRESH_GRANT = zend_hash_str_find_ptr(EG(zend_constants), "MYSQLI_REFRESH_GRANT", sizeof("MYSQLI_REFRESH_GRANT") - 1); + + 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 attribute_Deprecated_const_MYSQLI_REFRESH_GRANT_0_arg0; + zend_string *attribute_Deprecated_const_MYSQLI_REFRESH_GRANT_0_arg0_str = zend_string_init("8.4", strlen("8.4"), 1); + ZVAL_STR(&attribute_Deprecated_const_MYSQLI_REFRESH_GRANT_0_arg0, attribute_Deprecated_const_MYSQLI_REFRESH_GRANT_0_arg0_str); + ZVAL_COPY_VALUE(&attribute_Deprecated_const_MYSQLI_REFRESH_GRANT_0->args[0].value, &attribute_Deprecated_const_MYSQLI_REFRESH_GRANT_0_arg0); + 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); + attribute_Deprecated_const_MYSQLI_REFRESH_GRANT_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + zend_constant *const_MYSQLI_REFRESH_LOG = zend_hash_str_find_ptr(EG(zend_constants), "MYSQLI_REFRESH_LOG", sizeof("MYSQLI_REFRESH_LOG") - 1); + + 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 attribute_Deprecated_const_MYSQLI_REFRESH_LOG_0_arg0; + zend_string *attribute_Deprecated_const_MYSQLI_REFRESH_LOG_0_arg0_str = zend_string_init("8.4", strlen("8.4"), 1); + ZVAL_STR(&attribute_Deprecated_const_MYSQLI_REFRESH_LOG_0_arg0, attribute_Deprecated_const_MYSQLI_REFRESH_LOG_0_arg0_str); + ZVAL_COPY_VALUE(&attribute_Deprecated_const_MYSQLI_REFRESH_LOG_0->args[0].value, &attribute_Deprecated_const_MYSQLI_REFRESH_LOG_0_arg0); + 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); + attribute_Deprecated_const_MYSQLI_REFRESH_LOG_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + zend_constant *const_MYSQLI_REFRESH_TABLES = zend_hash_str_find_ptr(EG(zend_constants), "MYSQLI_REFRESH_TABLES", sizeof("MYSQLI_REFRESH_TABLES") - 1); + + 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 attribute_Deprecated_const_MYSQLI_REFRESH_TABLES_0_arg0; + zend_string *attribute_Deprecated_const_MYSQLI_REFRESH_TABLES_0_arg0_str = zend_string_init("8.4", strlen("8.4"), 1); + ZVAL_STR(&attribute_Deprecated_const_MYSQLI_REFRESH_TABLES_0_arg0, attribute_Deprecated_const_MYSQLI_REFRESH_TABLES_0_arg0_str); + ZVAL_COPY_VALUE(&attribute_Deprecated_const_MYSQLI_REFRESH_TABLES_0->args[0].value, &attribute_Deprecated_const_MYSQLI_REFRESH_TABLES_0_arg0); + 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); + attribute_Deprecated_const_MYSQLI_REFRESH_TABLES_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + zend_constant *const_MYSQLI_REFRESH_HOSTS = zend_hash_str_find_ptr(EG(zend_constants), "MYSQLI_REFRESH_HOSTS", sizeof("MYSQLI_REFRESH_HOSTS") - 1); + + 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 attribute_Deprecated_const_MYSQLI_REFRESH_HOSTS_0_arg0; + zend_string *attribute_Deprecated_const_MYSQLI_REFRESH_HOSTS_0_arg0_str = zend_string_init("8.4", strlen("8.4"), 1); + ZVAL_STR(&attribute_Deprecated_const_MYSQLI_REFRESH_HOSTS_0_arg0, attribute_Deprecated_const_MYSQLI_REFRESH_HOSTS_0_arg0_str); + ZVAL_COPY_VALUE(&attribute_Deprecated_const_MYSQLI_REFRESH_HOSTS_0->args[0].value, &attribute_Deprecated_const_MYSQLI_REFRESH_HOSTS_0_arg0); + 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); + attribute_Deprecated_const_MYSQLI_REFRESH_HOSTS_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + zend_constant *const_MYSQLI_REFRESH_STATUS = zend_hash_str_find_ptr(EG(zend_constants), "MYSQLI_REFRESH_STATUS", sizeof("MYSQLI_REFRESH_STATUS") - 1); + + 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 attribute_Deprecated_const_MYSQLI_REFRESH_STATUS_0_arg0; + zend_string *attribute_Deprecated_const_MYSQLI_REFRESH_STATUS_0_arg0_str = zend_string_init("8.4", strlen("8.4"), 1); + ZVAL_STR(&attribute_Deprecated_const_MYSQLI_REFRESH_STATUS_0_arg0, attribute_Deprecated_const_MYSQLI_REFRESH_STATUS_0_arg0_str); + ZVAL_COPY_VALUE(&attribute_Deprecated_const_MYSQLI_REFRESH_STATUS_0->args[0].value, &attribute_Deprecated_const_MYSQLI_REFRESH_STATUS_0_arg0); + 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); + attribute_Deprecated_const_MYSQLI_REFRESH_STATUS_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + zend_constant *const_MYSQLI_REFRESH_THREADS = zend_hash_str_find_ptr(EG(zend_constants), "MYSQLI_REFRESH_THREADS", sizeof("MYSQLI_REFRESH_THREADS") - 1); + + 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 attribute_Deprecated_const_MYSQLI_REFRESH_THREADS_0_arg0; + zend_string *attribute_Deprecated_const_MYSQLI_REFRESH_THREADS_0_arg0_str = zend_string_init("8.4", strlen("8.4"), 1); + ZVAL_STR(&attribute_Deprecated_const_MYSQLI_REFRESH_THREADS_0_arg0, attribute_Deprecated_const_MYSQLI_REFRESH_THREADS_0_arg0_str); + ZVAL_COPY_VALUE(&attribute_Deprecated_const_MYSQLI_REFRESH_THREADS_0->args[0].value, &attribute_Deprecated_const_MYSQLI_REFRESH_THREADS_0_arg0); + 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); + attribute_Deprecated_const_MYSQLI_REFRESH_THREADS_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + zend_constant *const_MYSQLI_REFRESH_REPLICA = zend_hash_str_find_ptr(EG(zend_constants), "MYSQLI_REFRESH_REPLICA", sizeof("MYSQLI_REFRESH_REPLICA") - 1); + + 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 attribute_Deprecated_const_MYSQLI_REFRESH_REPLICA_0_arg0; + zend_string *attribute_Deprecated_const_MYSQLI_REFRESH_REPLICA_0_arg0_str = zend_string_init("8.4", strlen("8.4"), 1); + ZVAL_STR(&attribute_Deprecated_const_MYSQLI_REFRESH_REPLICA_0_arg0, attribute_Deprecated_const_MYSQLI_REFRESH_REPLICA_0_arg0_str); + ZVAL_COPY_VALUE(&attribute_Deprecated_const_MYSQLI_REFRESH_REPLICA_0->args[0].value, &attribute_Deprecated_const_MYSQLI_REFRESH_REPLICA_0_arg0); + 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); + attribute_Deprecated_const_MYSQLI_REFRESH_REPLICA_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + zend_constant *const_MYSQLI_REFRESH_SLAVE = zend_hash_str_find_ptr(EG(zend_constants), "MYSQLI_REFRESH_SLAVE", sizeof("MYSQLI_REFRESH_SLAVE") - 1); + + 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 attribute_Deprecated_const_MYSQLI_REFRESH_SLAVE_0_arg0; + zend_string *attribute_Deprecated_const_MYSQLI_REFRESH_SLAVE_0_arg0_str = zend_string_init("8.4", strlen("8.4"), 1); + ZVAL_STR(&attribute_Deprecated_const_MYSQLI_REFRESH_SLAVE_0_arg0, attribute_Deprecated_const_MYSQLI_REFRESH_SLAVE_0_arg0_str); + ZVAL_COPY_VALUE(&attribute_Deprecated_const_MYSQLI_REFRESH_SLAVE_0->args[0].value, &attribute_Deprecated_const_MYSQLI_REFRESH_SLAVE_0_arg0); + 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); + attribute_Deprecated_const_MYSQLI_REFRESH_SLAVE_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + zend_constant *const_MYSQLI_REFRESH_MASTER = zend_hash_str_find_ptr(EG(zend_constants), "MYSQLI_REFRESH_MASTER", sizeof("MYSQLI_REFRESH_MASTER") - 1); + + 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 attribute_Deprecated_const_MYSQLI_REFRESH_MASTER_0_arg0; + zend_string *attribute_Deprecated_const_MYSQLI_REFRESH_MASTER_0_arg0_str = zend_string_init("8.4", strlen("8.4"), 1); + ZVAL_STR(&attribute_Deprecated_const_MYSQLI_REFRESH_MASTER_0_arg0, attribute_Deprecated_const_MYSQLI_REFRESH_MASTER_0_arg0_str); + ZVAL_COPY_VALUE(&attribute_Deprecated_const_MYSQLI_REFRESH_MASTER_0->args[0].value, &attribute_Deprecated_const_MYSQLI_REFRESH_MASTER_0_arg0); + 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); + attribute_Deprecated_const_MYSQLI_REFRESH_MASTER_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + zend_constant *const_MYSQLI_REFRESH_BACKUP_LOG = zend_hash_str_find_ptr(EG(zend_constants), "MYSQLI_REFRESH_BACKUP_LOG", sizeof("MYSQLI_REFRESH_BACKUP_LOG") - 1); + + 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 attribute_Deprecated_const_MYSQLI_REFRESH_BACKUP_LOG_0_arg0; + zend_string *attribute_Deprecated_const_MYSQLI_REFRESH_BACKUP_LOG_0_arg0_str = zend_string_init("8.4", strlen("8.4"), 1); + ZVAL_STR(&attribute_Deprecated_const_MYSQLI_REFRESH_BACKUP_LOG_0_arg0, attribute_Deprecated_const_MYSQLI_REFRESH_BACKUP_LOG_0_arg0_str); + ZVAL_COPY_VALUE(&attribute_Deprecated_const_MYSQLI_REFRESH_BACKUP_LOG_0->args[0].value, &attribute_Deprecated_const_MYSQLI_REFRESH_BACKUP_LOG_0_arg0); + 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); + attribute_Deprecated_const_MYSQLI_REFRESH_BACKUP_LOG_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + zend_constant *const_MYSQLI_IS_MARIADB = zend_hash_str_find_ptr(EG(zend_constants), "MYSQLI_IS_MARIADB", sizeof("MYSQLI_IS_MARIADB") - 1); + + 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 attribute_Deprecated_const_MYSQLI_IS_MARIADB_0_arg0; + zend_string *attribute_Deprecated_const_MYSQLI_IS_MARIADB_0_arg0_str = zend_string_init("8.2", strlen("8.2"), 1); + ZVAL_STR(&attribute_Deprecated_const_MYSQLI_IS_MARIADB_0_arg0, attribute_Deprecated_const_MYSQLI_IS_MARIADB_0_arg0_str); + ZVAL_COPY_VALUE(&attribute_Deprecated_const_MYSQLI_IS_MARIADB_0->args[0].value, &attribute_Deprecated_const_MYSQLI_IS_MARIADB_0_arg0); + 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); + attribute_Deprecated_const_MYSQLI_IS_MARIADB_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); } static zend_class_entry *register_class_mysqli_driver(void) diff --git a/ext/mysqli/mysqli_report.c b/ext/mysqli/mysqli_report.c index 68a7a57584750..06611310b0b0c 100644 --- a/ext/mysqli/mysqli_report.c +++ b/ext/mysqli/mysqli_report.c @@ -48,12 +48,12 @@ void php_mysqli_report_error(const char *sqlstate, int errorno, const char *erro /* {{{ void php_mysqli_report_index() */ void php_mysqli_report_index(const char *query, unsigned int status) { - char index[15]; + const char *index; if (status & SERVER_QUERY_NO_GOOD_INDEX_USED) { - strcpy(index, "Bad index"); + index = "Bad index"; } else if (status & SERVER_QUERY_NO_INDEX_USED) { - strcpy(index, "No index"); + index = "No index"; } else { return; } diff --git a/ext/mysqli/tests/deprecated_constants.phpt b/ext/mysqli/tests/deprecated_constants.phpt index 9c8e06e50fe1c..753863a3bf131 100644 --- a/ext/mysqli/tests/deprecated_constants.phpt +++ b/ext/mysqli/tests/deprecated_constants.phpt @@ -16,22 +16,22 @@ echo constant('MYSQLI_IS_MARIADB')."\n"; ?> --EXPECTF-- -Deprecated: Constant MYSQLI_NO_DATA is deprecated in %s +Deprecated: Constant MYSQLI_NO_DATA is deprecated since 8.1, as it was unused in %s %i -Deprecated: Constant MYSQLI_DATA_TRUNCATED is deprecated in %s +Deprecated: Constant MYSQLI_DATA_TRUNCATED is deprecated since 8.1, as it was unused in %s %i -Deprecated: Constant MYSQLI_SERVER_QUERY_NO_GOOD_INDEX_USED is deprecated in %s +Deprecated: Constant MYSQLI_SERVER_QUERY_NO_GOOD_INDEX_USED is deprecated since 8.1, as it was unused in %s %i -Deprecated: Constant MYSQLI_SERVER_QUERY_NO_INDEX_USED is deprecated in %s +Deprecated: Constant MYSQLI_SERVER_QUERY_NO_INDEX_USED is deprecated since 8.1, as it was unused in %s %i -Deprecated: Constant MYSQLI_SERVER_QUERY_WAS_SLOW is deprecated in %s +Deprecated: Constant MYSQLI_SERVER_QUERY_WAS_SLOW is deprecated since 8.1, as it was unused in %s %i -Deprecated: Constant MYSQLI_SERVER_PS_OUT_PARAMS is deprecated in %s +Deprecated: Constant MYSQLI_SERVER_PS_OUT_PARAMS is deprecated since 8.1, as it was unused in %s %i -Deprecated: Constant MYSQLI_IS_MARIADB is deprecated in %s +Deprecated: Constant MYSQLI_IS_MARIADB is deprecated since 8.2, as it is always false in %s diff --git a/ext/opcache/jit/zend_jit.c b/ext/opcache/jit/zend_jit.c index bdf8ce2b007f4..fa2cc10e8b3a0 100644 --- a/ext/opcache/jit/zend_jit.c +++ b/ext/opcache/jit/zend_jit.c @@ -3363,6 +3363,17 @@ int zend_jit_op_array(zend_op_array *op_array, zend_script *script) return FAILURE; } +static void zend_jit_link_func_info(zend_op_array *op_array) +{ + if (!ZEND_FUNC_INFO(op_array)) { + void *jit_extension = zend_shared_alloc_get_xlat_entry(op_array->opcodes); + + if (jit_extension) { + ZEND_SET_FUNC_INFO(op_array, jit_extension); + } + } +} + int zend_jit_script(zend_script *script) { void *checkpoint; @@ -3450,6 +3461,7 @@ int zend_jit_script(zend_script *script) zend_class_entry *ce; zend_op_array *op_array; zval *zv; + zend_property_info *prop; ZEND_HASH_MAP_FOREACH_VAL(&script->class_table, zv) { if (Z_TYPE_P(zv) == IS_ALIAS_PTR) { @@ -3460,14 +3472,21 @@ int zend_jit_script(zend_script *script) ZEND_ASSERT(ce->type == ZEND_USER_CLASS); ZEND_HASH_MAP_FOREACH_PTR(&ce->function_table, op_array) { - if (!ZEND_FUNC_INFO(op_array)) { - void *jit_extension = zend_shared_alloc_get_xlat_entry(op_array->opcodes); + zend_jit_link_func_info(op_array); + } ZEND_HASH_FOREACH_END(); - if (jit_extension) { - ZEND_SET_FUNC_INFO(op_array, jit_extension); + if (ce->num_hooked_props > 0) { + ZEND_HASH_MAP_FOREACH_PTR(&ce->properties_info, prop) { + if (prop->hooks) { + for (uint32_t i = 0; i < ZEND_PROPERTY_HOOK_COUNT; i++) { + if (prop->hooks[i]) { + op_array = &prop->hooks[i]->op_array; + zend_jit_link_func_info(op_array); + } + } } - } - } ZEND_HASH_FOREACH_END(); + } ZEND_HASH_FOREACH_END(); + } } ZEND_HASH_FOREACH_END(); } diff --git a/ext/opcache/tests/func_info.phpt b/ext/opcache/tests/func_info.phpt index 8b1f9ef436c4b..9596aa23199d2 100644 --- a/ext/opcache/tests/func_info.phpt +++ b/ext/opcache/tests/func_info.phpt @@ -16,7 +16,7 @@ foreach (get_defined_functions()["internal"] as $function) { if (in_array($function, ["extract", "compact", "get_defined_vars"])) { continue; } - $contents .= " \$result = {$function}();\n"; + $contents .= " \$result = \\{$function}();\n"; } $contents .= "}\n"; diff --git a/ext/opcache/tests/jit/gh18898_1.phpt b/ext/opcache/tests/jit/gh18898_1.phpt new file mode 100644 index 0000000000000..6038f006f5e5c --- /dev/null +++ b/ext/opcache/tests/jit/gh18898_1.phpt @@ -0,0 +1,23 @@ +--TEST-- +GH-18898 (SEGV zend_jit_op_array_hot with property hooks and preloading) - jit 1235 +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.jit=1235 +opcache.jit_buffer_size=16M +opcache.preload={PWD}/../gh18534_preload.inc +--EXTENSIONS-- +opcache +--SKIPIF-- + +--FILE-- +dummyProperty2); +echo "ok"; +?> +--EXPECT-- +NULL +ok diff --git a/ext/opcache/tests/jit/gh18898_2.phpt b/ext/opcache/tests/jit/gh18898_2.phpt new file mode 100644 index 0000000000000..0ce79b859a979 --- /dev/null +++ b/ext/opcache/tests/jit/gh18898_2.phpt @@ -0,0 +1,23 @@ +--TEST-- +GH-18898 (SEGV zend_jit_op_array_hot with property hooks and preloading) - jit 1233 +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.jit=1233 +opcache.jit_buffer_size=16M +opcache.preload={PWD}/../gh18534_preload.inc +--EXTENSIONS-- +opcache +--SKIPIF-- + +--FILE-- +dummyProperty2); +echo "ok"; +?> +--EXPECT-- +NULL +ok diff --git a/ext/opcache/zend_accelerator_module.c b/ext/opcache/zend_accelerator_module.c index 203a41d93b40a..a4f632872f546 100644 --- a/ext/opcache/zend_accelerator_module.c +++ b/ext/opcache/zend_accelerator_module.c @@ -323,7 +323,7 @@ ZEND_INI_BEGIN() STD_PHP_INI_ENTRY("opcache.jit_max_root_traces" , "1024", PHP_INI_SYSTEM, OnUpdateLong, max_root_traces, zend_jit_globals, jit_globals) STD_PHP_INI_ENTRY("opcache.jit_max_side_traces" , "128", PHP_INI_SYSTEM, OnUpdateLong, max_side_traces, zend_jit_globals, jit_globals) STD_PHP_INI_ENTRY("opcache.jit_max_exit_counters" , "8192", PHP_INI_SYSTEM, OnUpdateLong, max_exit_counters, zend_jit_globals, jit_globals) - /* Defautl value should be a prime number, to reduce the chances of loop iterations being a factor of opcache.jit_hot_loop */ + /* Default value should be a prime number, to reduce the chances of loop iterations being a factor of opcache.jit_hot_loop */ STD_PHP_INI_ENTRY("opcache.jit_hot_loop" , "61", PHP_INI_SYSTEM, OnUpdateCounter, hot_loop, zend_jit_globals, jit_globals) STD_PHP_INI_ENTRY("opcache.jit_hot_func" , "127", PHP_INI_SYSTEM, OnUpdateCounter, hot_func, zend_jit_globals, jit_globals) STD_PHP_INI_ENTRY("opcache.jit_hot_return" , "8", PHP_INI_SYSTEM, OnUpdateCounter, hot_return, zend_jit_globals, jit_globals) diff --git a/ext/opcache/zend_persist.c b/ext/opcache/zend_persist.c index 202cd73c90422..05a7cb00077c1 100644 --- a/ext/opcache/zend_persist.c +++ b/ext/opcache/zend_persist.c @@ -1283,6 +1283,41 @@ void zend_update_parent_ce(zend_class_entry *ce) } } +#ifdef HAVE_JIT +static void zend_accel_persist_jit_op_array(zend_op_array *op_array, zend_class_entry *ce) +{ + if (op_array->type == ZEND_USER_FUNCTION) { + if (op_array->scope == ce + && !(op_array->fn_flags & ZEND_ACC_ABSTRACT) + && !(op_array->fn_flags & ZEND_ACC_TRAIT_CLONE)) { + zend_jit_op_array(op_array, ZCG(current_persistent_script) ? &ZCG(current_persistent_script)->script : NULL); + for (uint32_t i = 0; i < op_array->num_dynamic_func_defs; i++) { + zend_jit_op_array(op_array->dynamic_func_defs[i], ZCG(current_persistent_script) ? &ZCG(current_persistent_script)->script : NULL); + } + } + } +} + +static void zend_accel_persist_link_func_info(zend_op_array *op_array, zend_class_entry *ce) +{ + if (op_array->type == ZEND_USER_FUNCTION + && !(op_array->fn_flags & ZEND_ACC_ABSTRACT)) { + if ((op_array->scope != ce + || (op_array->fn_flags & ZEND_ACC_TRAIT_CLONE)) + && (JIT_G(trigger) == ZEND_JIT_ON_FIRST_EXEC + || JIT_G(trigger) == ZEND_JIT_ON_PROF_REQUEST + || JIT_G(trigger) == ZEND_JIT_ON_HOT_COUNTERS + || JIT_G(trigger) == ZEND_JIT_ON_HOT_TRACE)) { + void *jit_extension = zend_shared_alloc_get_xlat_entry(op_array->opcodes); + + if (jit_extension) { + ZEND_SET_FUNC_INFO(op_array, jit_extension); + } + } + } +} +#endif + static void zend_accel_persist_class_table(HashTable *class_table) { Bucket *p; @@ -1309,44 +1344,48 @@ static void zend_accel_persist_class_table(HashTable *class_table) if (JIT_G(on) && JIT_G(opt_level) <= ZEND_JIT_LEVEL_OPT_FUNCS && !ZCG(current_persistent_script)->corrupted) { zend_op_array *op_array; + zend_property_info *prop; ZEND_HASH_MAP_FOREACH_BUCKET(class_table, p) { if (EXPECTED(Z_TYPE(p->val) != IS_ALIAS_PTR)) { ce = Z_PTR(p->val); ZEND_HASH_MAP_FOREACH_PTR(&ce->function_table, op_array) { - if (op_array->type == ZEND_USER_FUNCTION) { - if (op_array->scope == ce - && !(op_array->fn_flags & ZEND_ACC_ABSTRACT) - && !(op_array->fn_flags & ZEND_ACC_TRAIT_CLONE)) { - zend_jit_op_array(op_array, ZCG(current_persistent_script) ? &ZCG(current_persistent_script)->script : NULL); - for (uint32_t i = 0; i < op_array->num_dynamic_func_defs; i++) { - zend_jit_op_array(op_array->dynamic_func_defs[i], ZCG(current_persistent_script) ? &ZCG(current_persistent_script)->script : NULL); + zend_accel_persist_jit_op_array(op_array, ce); + } ZEND_HASH_FOREACH_END(); + + if (ce->num_hooked_props > 0) { + ZEND_HASH_MAP_FOREACH_PTR(&ce->properties_info, prop) { + if (prop->hooks) { + for (uint32_t i = 0; i < ZEND_PROPERTY_HOOK_COUNT; i++) { + if (prop->hooks[i]) { + op_array = &prop->hooks[i]->op_array; + zend_accel_persist_jit_op_array(op_array, ce); + } } } - } - } ZEND_HASH_FOREACH_END(); + } ZEND_HASH_FOREACH_END(); + } } } ZEND_HASH_FOREACH_END(); ZEND_HASH_MAP_FOREACH_BUCKET(class_table, p) { if (EXPECTED(Z_TYPE(p->val) != IS_ALIAS_PTR)) { ce = Z_PTR(p->val); ZEND_HASH_MAP_FOREACH_PTR(&ce->function_table, op_array) { - if (op_array->type == ZEND_USER_FUNCTION - && !(op_array->fn_flags & ZEND_ACC_ABSTRACT)) { - if ((op_array->scope != ce - || (op_array->fn_flags & ZEND_ACC_TRAIT_CLONE)) - && (JIT_G(trigger) == ZEND_JIT_ON_FIRST_EXEC - || JIT_G(trigger) == ZEND_JIT_ON_PROF_REQUEST - || JIT_G(trigger) == ZEND_JIT_ON_HOT_COUNTERS - || JIT_G(trigger) == ZEND_JIT_ON_HOT_TRACE)) { - void *jit_extension = zend_shared_alloc_get_xlat_entry(op_array->opcodes); - - if (jit_extension) { - ZEND_SET_FUNC_INFO(op_array, jit_extension); + zend_accel_persist_link_func_info(op_array, ce); + } ZEND_HASH_FOREACH_END(); + + if (ce->num_hooked_props > 0) { + ZEND_HASH_MAP_FOREACH_PTR(&ce->properties_info, prop) { + if (prop->hooks) { + for (uint32_t i = 0; i < ZEND_PROPERTY_HOOK_COUNT; i++) { + if (prop->hooks[i]) { + op_array = &prop->hooks[i]->op_array; + zend_accel_persist_link_func_info(op_array, ce); + } } } - } - } ZEND_HASH_FOREACH_END(); + } ZEND_HASH_FOREACH_END(); + } } } ZEND_HASH_FOREACH_END(); } diff --git a/ext/pcntl/config.m4 b/ext/pcntl/config.m4 index ce26a6efd2ead..cfe6e80ca1103 100644 --- a/ext/pcntl/config.m4 +++ b/ext/pcntl/config.m4 @@ -13,7 +13,6 @@ if test "$PHP_PCNTL" != "no"; then forkx getcpuid getpriority - pidfd_open pset_bind pthread_set_qos_class_self_np rfork @@ -25,6 +24,8 @@ if test "$PHP_PCNTL" != "no"; then wait3 wait4 waitid + wait6 + syscall ])) AC_CHECK_FUNCS([WIFCONTINUED],, @@ -43,6 +44,12 @@ if test "$PHP_PCNTL" != "no"; then ]),,, [#include ]) + AC_CHECK_DECLS([SYS_waitid],,, + [#include ]) + + AC_CHECK_DECLS([SYS_pidfd_open],,, + [#include ]) + dnl if unsupported, -1 means automatically ENOSYS in this context AC_CACHE_CHECK([if sched_getcpu is supported], [php_cv_func_sched_getcpu], [AC_RUN_IFELSE([AC_LANG_SOURCE([ diff --git a/ext/pcntl/pcntl.c b/ext/pcntl/pcntl.c index 0481c0966c87a..6558ef8dcdd04 100644 --- a/ext/pcntl/pcntl.c +++ b/ext/pcntl/pcntl.c @@ -125,8 +125,18 @@ typedef psetid_t cpu_set_t; #include #endif -#ifdef HAVE_PIDFD_OPEN -#include +#if defined(__linux__) && defined(HAVE_SYSCALL) +# include +# if defined(HAVE_DECL_SYS_WAITID) && HAVE_DECL_SYS_WAITID == 1 +# define HAVE_LINUX_RAW_SYSCALL_WAITID 1 +# endif +# if defined(HAVE_DECL_SYS_PIDFD_OPEN) && HAVE_DECL_SYS_PIDFD_OPEN == 1 +# define HAVE_LINUX_RAW_SYSCALL_PIDFD_OPEN 1 +# endif +#endif + +#if defined(HAVE_LINUX_RAW_SYSCALL_WAITID) +#include #endif #ifdef HAVE_FORKX @@ -401,19 +411,49 @@ PHP_FUNCTION(pcntl_waitid) bool id_is_null = 1; zval *user_siginfo = NULL; zend_long options = WEXITED; + zval *z_rusage = NULL; + + siginfo_t siginfo; + int status; - ZEND_PARSE_PARAMETERS_START(0, 4) + ZEND_PARSE_PARAMETERS_START(0, 5) Z_PARAM_OPTIONAL Z_PARAM_LONG(idtype) Z_PARAM_LONG_OR_NULL(id, id_is_null) Z_PARAM_ZVAL(user_siginfo) Z_PARAM_LONG(options) + Z_PARAM_ZVAL(z_rusage) ZEND_PARSE_PARAMETERS_END(); errno = 0; - siginfo_t siginfo; + memset(&siginfo, 0, sizeof(siginfo_t)); - int status = waitid((idtype_t) idtype, (id_t) id, &siginfo, (int) options); +#if defined(HAVE_WAIT6) || defined(HAVE_LINUX_RAW_SYSCALL_WAITID) + if (z_rusage) { + z_rusage = zend_try_array_init(z_rusage); + if (!z_rusage) { + RETURN_THROWS(); + } + struct rusage rusage; +# if defined(HAVE_WAIT6) /* FreeBSD */ + struct __wrusage wrusage; + memset(&wrusage, 0, sizeof(struct __wrusage)); + pid_t pid = wait6((idtype_t) idtype, (id_t) id, &status, (int) options, &wrusage, &siginfo); + status = pid > 0 ? 0 : pid; + memcpy(&rusage, &wrusage.wru_self, sizeof(struct rusage)); +# else /* Linux */ + memset(&rusage, 0, sizeof(struct rusage)); + status = syscall(SYS_waitid, (idtype_t) idtype, (id_t) id, &siginfo, (int) options, &rusage); +# endif + if (status == 0) { + PHP_RUSAGE_TO_ARRAY(rusage, z_rusage); + } + } else { /* POSIX */ + status = waitid((idtype_t) idtype, (id_t) id, &siginfo, (int) options); + } +#else /* POSIX */ + status = waitid((idtype_t) idtype, (id_t) id, &siginfo, (int) options); +#endif if (status == -1) { PCNTL_G(last_error) = errno; @@ -1519,6 +1559,8 @@ PHP_FUNCTION(pcntl_rfork) default: php_error_docref(NULL, E_WARNING, "Error %d", errno); } + } else if (pid == 0) { + zend_max_execution_timer_init(); } RETURN_LONG((zend_long) pid); @@ -1562,6 +1604,8 @@ PHP_FUNCTION(pcntl_forkx) default: php_error_docref(NULL, E_WARNING, "Error %d", errno); } + } else if (pid == 0) { + zend_max_execution_timer_init(); } RETURN_LONG((zend_long) pid); @@ -1569,7 +1613,7 @@ PHP_FUNCTION(pcntl_forkx) #endif /* }}} */ -#ifdef HAVE_PIDFD_OPEN +#ifdef HAVE_LINUX_RAW_SYSCALL_PIDFD_OPEN // The `pidfd_open` syscall is available since 5.3 // and `setns` since 3.0. PHP_FUNCTION(pcntl_setns) diff --git a/ext/pcntl/pcntl.stub.php b/ext/pcntl/pcntl.stub.php index c62a40139d9ed..3f3800c50abe5 100644 --- a/ext/pcntl/pcntl.stub.php +++ b/ext/pcntl/pcntl.stub.php @@ -1006,8 +1006,11 @@ function pcntl_fork(): int {} function pcntl_waitpid(int $process_id, &$status, int $flags = 0, &$resource_usage = []): int {} #if defined (HAVE_WAITID) && defined (HAVE_POSIX_IDTYPES) && defined (HAVE_DECL_WEXITED) && HAVE_DECL_WEXITED == 1 - /** @param array $info */ - function pcntl_waitid(int $idtype = P_ALL, ?int $id = null, &$info = [], int $flags = WEXITED): bool {} + /** + * @param array $info + * @param array $resource_usage + */ + function pcntl_waitid(int $idtype = P_ALL, ?int $id = null, &$info = [], int $flags = WEXITED, &$resource_usage = []): bool {} #endif /** diff --git a/ext/pcntl/pcntl_arginfo.h b/ext/pcntl/pcntl_arginfo.h index bc6581d41e17e..8b2367a7c7042 100644 --- a/ext/pcntl/pcntl_arginfo.h +++ b/ext/pcntl/pcntl_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: c637fe2de641cfd8f0ff83a908ac59bf63a68e44 */ + * Stub hash: 5e4b066d70fa264c7de3ba4b2113369c34c33e43 */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_pcntl_fork, 0, 0, IS_LONG, 0) ZEND_END_ARG_INFO() @@ -17,6 +17,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_pcntl_waitid, 0, 0, _IS_BOOL, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, id, IS_LONG, 1, "null") ZEND_ARG_INFO_WITH_DEFAULT_VALUE(1, info, "[]") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, flags, IS_LONG, 0, "WEXITED") + ZEND_ARG_INFO_WITH_DEFAULT_VALUE(1, resource_usage, "[]") ZEND_END_ARG_INFO() #endif diff --git a/ext/pcntl/tests/pcntl_waitid.phpt b/ext/pcntl/tests/pcntl_waitid.phpt index b00f26f81fa2e..e297cd107a473 100644 --- a/ext/pcntl/tests/pcntl_waitid.phpt +++ b/ext/pcntl/tests/pcntl_waitid.phpt @@ -26,10 +26,12 @@ if ($pid == -1) { } else { pcntl_signal(SIGUSR1, function ($_signo, $_siginfo) { exit(42); }); posix_kill(posix_getpid(), SIGSTOP); - pcntl_signal_dispatch(); - sleep(42); - pcntl_signal_dispatch(); - exit(6); + $nanoseconds = 100; + while (true) { + pcntl_signal_dispatch(); + time_nanosleep(0, $nanoseconds); + $nanoseconds *= 2; + } } ?> --EXPECTF-- diff --git a/ext/pcntl/tests/pcntl_waitid_rusage.phpt b/ext/pcntl/tests/pcntl_waitid_rusage.phpt new file mode 100644 index 0000000000000..8df148357d1c8 --- /dev/null +++ b/ext/pcntl/tests/pcntl_waitid_rusage.phpt @@ -0,0 +1,72 @@ +--TEST-- +pcntl_waitid() and rusage +--EXTENSIONS-- +pcntl +posix +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +bool(true) +int(%d) +int(%d) +bool(true) +int(%d) +int(%d) +bool(true) +int(%d) +int(42) +bool(false) +string(5) "array" +int(0) +bool(false) +string(5) "array" +int(0) +END diff --git a/ext/pdo_pgsql/pgsql_driver.c b/ext/pdo_pgsql/pgsql_driver.c index 4895463db4b08..35b86a3588fdc 100644 --- a/ext/pdo_pgsql/pgsql_driver.c +++ b/ext/pdo_pgsql/pgsql_driver.c @@ -378,11 +378,15 @@ static zend_string* pgsql_handle_quoter(pdo_dbh_t *dbh, const zend_string *unquo zend_string *quoted_str; pdo_pgsql_db_handle *H = (pdo_pgsql_db_handle *)dbh->driver_data; size_t tmp_len; + int err; switch (paramtype) { case PDO_PARAM_LOB: /* escapedlen returned by PQescapeBytea() accounts for trailing 0 */ escaped = PQescapeByteaConn(H->server, (unsigned char *)ZSTR_VAL(unquoted), ZSTR_LEN(unquoted), &tmp_len); + if (escaped == NULL) { + return NULL; + } quotedlen = tmp_len + 1; quoted = emalloc(quotedlen + 1); memcpy(quoted+1, escaped, quotedlen-2); @@ -394,7 +398,11 @@ static zend_string* pgsql_handle_quoter(pdo_dbh_t *dbh, const zend_string *unquo default: quoted = safe_emalloc(2, ZSTR_LEN(unquoted), 3); quoted[0] = '\''; - quotedlen = PQescapeStringConn(H->server, quoted + 1, ZSTR_VAL(unquoted), ZSTR_LEN(unquoted), NULL); + quotedlen = PQescapeStringConn(H->server, quoted + 1, ZSTR_VAL(unquoted), ZSTR_LEN(unquoted), &err); + if (err) { + efree(quoted); + return NULL; + } quoted[quotedlen + 1] = '\''; quoted[quotedlen + 2] = '\0'; quotedlen += 2; diff --git a/ext/pdo_pgsql/tests/ghsa-hrwm-9436-5mv3.phpt b/ext/pdo_pgsql/tests/ghsa-hrwm-9436-5mv3.phpt new file mode 100644 index 0000000000000..8566a26753b40 --- /dev/null +++ b/ext/pdo_pgsql/tests/ghsa-hrwm-9436-5mv3.phpt @@ -0,0 +1,24 @@ +--TEST-- +#GHSA-hrwm-9436-5mv3: pdo_pgsql extension does not check for errors during escaping +--EXTENSIONS-- +pdo +pdo_pgsql +--SKIPIF-- + +--FILE-- +setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + +$invalid = "ABC\xff\x30';"; +var_dump($db->quote($invalid)); + +?> +--EXPECT-- +bool(false) diff --git a/ext/pgsql/pgsql.c b/ext/pgsql/pgsql.c index ba6d660d0307e..3d180e3d6b9da 100644 --- a/ext/pgsql/pgsql.c +++ b/ext/pgsql/pgsql.c @@ -3572,8 +3572,14 @@ PHP_FUNCTION(pg_escape_string) to = zend_string_safe_alloc(ZSTR_LEN(from), 2, 0, 0); if (link) { + int err; pgsql = link->conn; - ZSTR_LEN(to) = PQescapeStringConn(pgsql, ZSTR_VAL(to), ZSTR_VAL(from), ZSTR_LEN(from), NULL); + ZSTR_LEN(to) = PQescapeStringConn(pgsql, ZSTR_VAL(to), ZSTR_VAL(from), ZSTR_LEN(from), &err); + if (err) { + zend_argument_value_error(ZEND_NUM_ARGS(), "Escaping string failed"); + zend_string_efree(to); + RETURN_THROWS(); + } } else { ZSTR_LEN(to) = PQescapeString(ZSTR_VAL(to), ZSTR_VAL(from), ZSTR_LEN(from)); @@ -3619,6 +3625,10 @@ PHP_FUNCTION(pg_escape_bytea) } else { to = (char *)PQescapeBytea((unsigned char *)ZSTR_VAL(from), ZSTR_LEN(from), &to_len); } + if (to == NULL) { + zend_argument_value_error(ZEND_NUM_ARGS(), "Escape failure"); + RETURN_THROWS(); + } RETVAL_STRINGL(to, to_len-1); /* to_len includes additional '\0' */ PQfreemem(to); @@ -4572,7 +4582,7 @@ PHP_PGSQL_API zend_result php_pgsql_meta_data(PGconn *pg_link, const zend_string char *escaped; smart_str querystr = {0}; size_t new_len, len; - int i, num_rows; + int i, num_rows, err; zval elem; ZEND_ASSERT(ZSTR_LEN(table_name) != 0); @@ -4611,7 +4621,14 @@ PHP_PGSQL_API zend_result php_pgsql_meta_data(PGconn *pg_link, const zend_string } len = strlen(tmp_name2); escaped = (char *)safe_emalloc(len, 2, 1); - new_len = PQescapeStringConn(pg_link, escaped, tmp_name2, len, NULL); + new_len = PQescapeStringConn(pg_link, escaped, tmp_name2, len, &err); + if (err) { + php_error_docref(NULL, E_WARNING, "Escaping table name '%s' failed", ZSTR_VAL(table_name)); + efree(src); + efree(escaped); + smart_str_free(&querystr); + return FAILURE; + } if (new_len) { smart_str_appendl(&querystr, escaped, new_len); } @@ -4620,7 +4637,14 @@ PHP_PGSQL_API zend_result php_pgsql_meta_data(PGconn *pg_link, const zend_string smart_str_appends(&querystr, "' AND n.nspname = '"); len = strlen(tmp_name); escaped = (char *)safe_emalloc(len, 2, 1); - new_len = PQescapeStringConn(pg_link, escaped, tmp_name, len, NULL); + new_len = PQescapeStringConn(pg_link, escaped, tmp_name, len, &err); + if (err) { + php_error_docref(NULL, E_WARNING, "Escaping table namespace '%s' failed", ZSTR_VAL(table_name)); + efree(src); + efree(escaped); + smart_str_free(&querystr); + return FAILURE; + } if (new_len) { smart_str_appendl(&querystr, escaped, new_len); } @@ -4875,7 +4899,7 @@ PHP_PGSQL_API zend_result php_pgsql_convert(PGconn *pg_link, const zend_string * { zend_string *field = NULL; zval meta, *def, *type, *not_null, *has_default, *is_enum, *val, new_val; - int err = 0; + int err = 0, escape_err = 0; bool skip_field; php_pgsql_data_type data_type; @@ -5121,8 +5145,13 @@ PHP_PGSQL_API zend_result php_pgsql_convert(PGconn *pg_link, const zend_string * /* PostgreSQL ignores \0 */ str = zend_string_alloc(Z_STRLEN_P(val) * 2, 0); /* better to use PGSQLescapeLiteral since PGescapeStringConn does not handle special \ */ - ZSTR_LEN(str) = PQescapeStringConn(pg_link, ZSTR_VAL(str), Z_STRVAL_P(val), Z_STRLEN_P(val), NULL); - ZVAL_STR(&new_val, php_pgsql_add_quotes(str)); + ZSTR_LEN(str) = PQescapeStringConn(pg_link, ZSTR_VAL(str), + Z_STRVAL_P(val), Z_STRLEN_P(val), &escape_err); + if (escape_err) { + err = 1; + } else { + ZVAL_STR(&new_val, php_pgsql_add_quotes(str)); + } zend_string_release_ex(str, false); } break; @@ -5145,7 +5174,14 @@ PHP_PGSQL_API zend_result php_pgsql_convert(PGconn *pg_link, const zend_string * } PGSQL_CONV_CHECK_IGNORE(); if (err) { - zend_type_error("%s(): Field \"%s\" must be of type string|null, %s given", get_active_function_name(), ZSTR_VAL(field), Z_STRVAL_P(type)); + if (escape_err) { + php_error_docref(NULL, E_NOTICE, + "String value escaping failed for PostgreSQL '%s' (%s)", + Z_STRVAL_P(type), ZSTR_VAL(field)); + } else { + zend_type_error("%s(): Field \"%s\" must be of type string|null, %s given", + get_active_function_name(), ZSTR_VAL(field), Z_STRVAL_P(type)); + } } break; @@ -5379,6 +5415,11 @@ PHP_PGSQL_API zend_result php_pgsql_convert(PGconn *pg_link, const zend_string * zend_string *tmp_zstr; tmp = PQescapeByteaConn(pg_link, (unsigned char *)Z_STRVAL_P(val), Z_STRLEN_P(val), &to_len); + if (tmp == NULL) { + php_error_docref(NULL, E_NOTICE, "Escaping value failed for %s field (%s)", Z_STRVAL_P(type), ZSTR_VAL(field)); + err = 1; + break; + } tmp_zstr = zend_string_init((char *)tmp, to_len - 1, false); /* PQescapeBytea's to_len includes additional '\0' */ PQfreemem(tmp); @@ -5455,6 +5496,12 @@ PHP_PGSQL_API zend_result php_pgsql_convert(PGconn *pg_link, const zend_string * zend_hash_update(Z_ARRVAL_P(result), field, &new_val); } else { char *escaped = PQescapeIdentifier(pg_link, ZSTR_VAL(field), ZSTR_LEN(field)); + if (escaped == NULL) { + /* This cannot fail because of invalid string but only due to failed memory allocation */ + php_error_docref(NULL, E_NOTICE, "Escaping field '%s' failed", ZSTR_VAL(field)); + err = 1; + break; + } add_assoc_zval(result, escaped, &new_val); PQfreemem(escaped); } @@ -5537,7 +5584,7 @@ static bool do_exec(smart_str *querystr, ExecStatusType expect, PGconn *pg_link, } /* }}} */ -static inline void build_tablename(smart_str *querystr, PGconn *pg_link, const zend_string *table) /* {{{ */ +static inline zend_result build_tablename(smart_str *querystr, PGconn *pg_link, const zend_string *table) /* {{{ */ { /* schema.table should be "schema"."table" */ const char *dot = memchr(ZSTR_VAL(table), '.', ZSTR_LEN(table)); @@ -5547,6 +5594,10 @@ static inline void build_tablename(smart_str *querystr, PGconn *pg_link, const z smart_str_appendl(querystr, ZSTR_VAL(table), len); } else { char *escaped = PQescapeIdentifier(pg_link, ZSTR_VAL(table), len); + if (escaped == NULL) { + php_error_docref(NULL, E_NOTICE, "Failed to escape table name '%s'", ZSTR_VAL(table)); + return FAILURE; + } smart_str_appends(querystr, escaped); PQfreemem(escaped); } @@ -5559,11 +5610,17 @@ static inline void build_tablename(smart_str *querystr, PGconn *pg_link, const z smart_str_appendl(querystr, after_dot, len); } else { char *escaped = PQescapeIdentifier(pg_link, after_dot, len); + if (escaped == NULL) { + php_error_docref(NULL, E_NOTICE, "Failed to escape table name '%s'", ZSTR_VAL(table)); + return FAILURE; + } smart_str_appendc(querystr, '.'); smart_str_appends(querystr, escaped); PQfreemem(escaped); } } + + return SUCCESS; } /* }}} */ @@ -5584,7 +5641,9 @@ PHP_PGSQL_API zend_result php_pgsql_insert(PGconn *pg_link, const zend_string *t ZVAL_UNDEF(&converted); if (zend_hash_num_elements(Z_ARRVAL_P(var_array)) == 0) { smart_str_appends(&querystr, "INSERT INTO "); - build_tablename(&querystr, pg_link, table); + if (build_tablename(&querystr, pg_link, table) == FAILURE) { + goto cleanup; + } smart_str_appends(&querystr, " DEFAULT VALUES"); goto no_values; @@ -5600,7 +5659,9 @@ PHP_PGSQL_API zend_result php_pgsql_insert(PGconn *pg_link, const zend_string *t } smart_str_appends(&querystr, "INSERT INTO "); - build_tablename(&querystr, pg_link, table); + if (build_tablename(&querystr, pg_link, table) == FAILURE) { + goto cleanup; + } smart_str_appends(&querystr, " ("); ZEND_HASH_FOREACH_STR_KEY(Z_ARRVAL_P(var_array), fld) { @@ -5610,6 +5671,10 @@ PHP_PGSQL_API zend_result php_pgsql_insert(PGconn *pg_link, const zend_string *t } if (opt & PGSQL_DML_ESCAPE) { tmp = PQescapeIdentifier(pg_link, ZSTR_VAL(fld), ZSTR_LEN(fld) + 1); + if (tmp == NULL) { + php_error_docref(NULL, E_NOTICE, "Failed to escape field '%s'", ZSTR_VAL(fld)); + goto cleanup; + } smart_str_appends(&querystr, tmp); PQfreemem(tmp); } else { @@ -5621,15 +5686,19 @@ PHP_PGSQL_API zend_result php_pgsql_insert(PGconn *pg_link, const zend_string *t smart_str_appends(&querystr, ") VALUES ("); /* make values string */ - ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(var_array), val) { + ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(var_array), fld, val) { /* we can avoid the key_type check here, because we tested it in the other loop */ switch (Z_TYPE_P(val)) { case IS_STRING: if (opt & PGSQL_DML_ESCAPE) { - size_t new_len; - char *tmp; - tmp = (char *)safe_emalloc(Z_STRLEN_P(val), 2, 1); - new_len = PQescapeStringConn(pg_link, tmp, Z_STRVAL_P(val), Z_STRLEN_P(val), NULL); + int error; + char *tmp = safe_emalloc(Z_STRLEN_P(val), 2, 1); + size_t new_len = PQescapeStringConn(pg_link, tmp, Z_STRVAL_P(val), Z_STRLEN_P(val), &error); + if (error) { + php_error_docref(NULL, E_NOTICE, "Failed to escape field '%s' value", ZSTR_VAL(fld)); + efree(tmp); + goto cleanup; + } smart_str_appendc(&querystr, '\''); smart_str_appendl(&querystr, tmp, new_len); smart_str_appendc(&querystr, '\''); @@ -5787,6 +5856,10 @@ static inline int build_assignment_string(PGconn *pg_link, smart_str *querystr, } if (opt & PGSQL_DML_ESCAPE) { char *tmp = PQescapeIdentifier(pg_link, ZSTR_VAL(fld), ZSTR_LEN(fld) + 1); + if (tmp == NULL) { + php_error_docref(NULL, E_NOTICE, "Failed to escape field '%s'", ZSTR_VAL(fld)); + return -1; + } smart_str_appends(querystr, tmp); PQfreemem(tmp); } else { @@ -5802,8 +5875,14 @@ static inline int build_assignment_string(PGconn *pg_link, smart_str *querystr, switch (Z_TYPE_P(val)) { case IS_STRING: if (opt & PGSQL_DML_ESCAPE) { + int error; char *tmp = (char *)safe_emalloc(Z_STRLEN_P(val), 2, 1); - size_t new_len = PQescapeStringConn(pg_link, tmp, Z_STRVAL_P(val), Z_STRLEN_P(val), NULL); + size_t new_len = PQescapeStringConn(pg_link, tmp, Z_STRVAL_P(val), Z_STRLEN_P(val), &error); + if (error) { + php_error_docref(NULL, E_NOTICE, "Failed to escape field '%s' value", ZSTR_VAL(fld)); + efree(tmp); + return -1; + } smart_str_appendc(querystr, '\''); smart_str_appendl(querystr, tmp, new_len); smart_str_appendc(querystr, '\''); @@ -5871,7 +5950,9 @@ PHP_PGSQL_API zend_result php_pgsql_update(PGconn *pg_link, const zend_string *t } smart_str_appends(&querystr, "UPDATE "); - build_tablename(&querystr, pg_link, table); + if (build_tablename(&querystr, pg_link, table) == FAILURE) { + goto cleanup; + } smart_str_appends(&querystr, " SET "); if (build_assignment_string(pg_link, &querystr, Z_ARRVAL_P(var_array), 0, ",", 1, opt)) @@ -5977,7 +6058,9 @@ PHP_PGSQL_API zend_result php_pgsql_delete(PGconn *pg_link, const zend_string *t } smart_str_appends(&querystr, "DELETE FROM "); - build_tablename(&querystr, pg_link, table); + if (build_tablename(&querystr, pg_link, table) == FAILURE) { + goto cleanup; + } smart_str_appends(&querystr, " WHERE "); if (build_assignment_string(pg_link, &querystr, Z_ARRVAL_P(ids_array), 1, " AND ", sizeof(" AND ")-1, opt)) @@ -6121,7 +6204,9 @@ PHP_PGSQL_API zend_result php_pgsql_select(PGconn *pg_link, const zend_string *t } smart_str_appends(&querystr, "SELECT * FROM "); - build_tablename(&querystr, pg_link, table); + if (build_tablename(&querystr, pg_link, table) == FAILURE) { + goto cleanup; + } if (is_valid_ids_array) { smart_str_appends(&querystr, " WHERE "); diff --git a/ext/pgsql/pgsql.stub.php b/ext/pgsql/pgsql.stub.php index 04e648eff8d50..f379d115f6d45 100644 --- a/ext/pgsql/pgsql.stub.php +++ b/ext/pgsql/pgsql.stub.php @@ -13,8 +13,8 @@ /** * @var string * @cvalue pgsql_libpq_version - * @deprecated */ + #[\Deprecated(since: '8.0', message: 'as it is the same as PGSQL_LIBPQ_VERSION')] const PGSQL_LIBPQ_VERSION_STR = UNKNOWN; /* For connection option */ diff --git a/ext/pgsql/pgsql_arginfo.h b/ext/pgsql/pgsql_arginfo.h index cb58645e5e9f5..e42723eef6dd9 100644 --- a/ext/pgsql/pgsql_arginfo.h +++ b/ext/pgsql/pgsql_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 3cf44ca06d11cad086829d3d04900ade3cacb88b */ + * Stub hash: 7c5c32d94c0ac05313d8b19915c6318b0678b75b */ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_pg_connect, 0, 1, PgSql\\Connection, MAY_BE_FALSE) ZEND_ARG_TYPE_INFO(0, connection_string, IS_STRING, 0) @@ -1153,6 +1153,19 @@ static void register_pgsql_symbols(int module_number) 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); + zend_constant *const_PGSQL_LIBPQ_VERSION_STR = zend_hash_str_find_ptr(EG(zend_constants), "PGSQL_LIBPQ_VERSION_STR", sizeof("PGSQL_LIBPQ_VERSION_STR") - 1); + + 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 attribute_Deprecated_const_PGSQL_LIBPQ_VERSION_STR_0_arg0; + zend_string *attribute_Deprecated_const_PGSQL_LIBPQ_VERSION_STR_0_arg0_str = zend_string_init("8.0", strlen("8.0"), 1); + ZVAL_STR(&attribute_Deprecated_const_PGSQL_LIBPQ_VERSION_STR_0_arg0, attribute_Deprecated_const_PGSQL_LIBPQ_VERSION_STR_0_arg0_str); + ZVAL_COPY_VALUE(&attribute_Deprecated_const_PGSQL_LIBPQ_VERSION_STR_0->args[0].value, &attribute_Deprecated_const_PGSQL_LIBPQ_VERSION_STR_0_arg0); + 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); + attribute_Deprecated_const_PGSQL_LIBPQ_VERSION_STR_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); } static zend_class_entry *register_class_PgSql_Connection(void) diff --git a/ext/pgsql/tests/ghsa-hrwm-9436-5mv3.phpt b/ext/pgsql/tests/ghsa-hrwm-9436-5mv3.phpt new file mode 100644 index 0000000000000..6cbfe6d1f5859 --- /dev/null +++ b/ext/pgsql/tests/ghsa-hrwm-9436-5mv3.phpt @@ -0,0 +1,64 @@ +--TEST-- +#GHSA-hrwm-9436-5mv3: pgsql extension does not check for errors during escaping +--EXTENSIONS-- +pgsql +--SKIPIF-- + +--FILE-- + 'test'])); // table name str escape in php_pgsql_meta_data +var_dump(pg_insert($db, "$invalid.tbl", ['bar' => 'test'])); // schema name str escape in php_pgsql_meta_data +var_dump(pg_insert($db, 'ghsa_hrmw_9436_5mv3', ['bar' => $invalid])); // converted value str escape in php_pgsql_convert +var_dump(pg_insert($db, $invalid, [])); // ident escape in build_tablename +var_dump(pg_insert($db, 'ghsa_hrmw_9436_5mv3', [$invalid => 'foo'], $flags)); // ident escape for field php_pgsql_insert +var_dump(pg_insert($db, 'ghsa_hrmw_9436_5mv3', ['bar' => $invalid], $flags)); // str escape for field value in php_pgsql_insert +var_dump(pg_update($db, 'ghsa_hrmw_9436_5mv3', ['bar' => 'val'], [$invalid => 'test'], $flags)); // ident escape in build_assignment_string +var_dump(pg_update($db, 'ghsa_hrmw_9436_5mv3', ['bar' => 'val'], ['bar' => $invalid], $flags)); // invalid str escape in build_assignment_string +var_dump(pg_escape_literal($db, $invalid)); // pg_escape_literal escape +var_dump(pg_escape_identifier($db, $invalid)); // pg_escape_identifier escape + +?> +--EXPECTF-- + +Warning: pg_insert(): Escaping table name 'ABC%s';' failed in %s on line %d +bool(false) + +Warning: pg_insert(): Escaping table namespace 'ABC%s';.tbl' failed in %s on line %d +bool(false) + +Notice: pg_insert(): String value escaping failed for PostgreSQL 'text' (bar) in %s on line %d +bool(false) + +Notice: pg_insert(): Failed to escape table name 'ABC%s';' in %s on line %d +bool(false) + +Notice: pg_insert(): Failed to escape field 'ABC%s';' in %s on line %d +bool(false) + +Notice: pg_insert(): Failed to escape field 'bar' value in %s on line %d +bool(false) + +Notice: pg_update(): Failed to escape field 'ABC%s';' in %s on line %d +bool(false) + +Notice: pg_update(): Failed to escape field 'bar' value in %s on line %d +bool(false) + +Warning: pg_escape_literal(): Failed to escape in %s on line %d +bool(false) + +Warning: pg_escape_identifier(): Failed to escape in %s on line %d +bool(false) diff --git a/ext/random/random.stub.php b/ext/random/random.stub.php index b59221bf9180f..2854bdd2c2548 100644 --- a/ext/random/random.stub.php +++ b/ext/random/random.stub.php @@ -10,9 +10,9 @@ const MT_RAND_MT19937 = UNKNOWN; /** * @var int - * @deprecated * @cvalue MT_RAND_PHP */ + #[\Deprecated(since: '8.3', message: 'as it uses a biased non-standard variant of Mt19937')] const MT_RAND_PHP = UNKNOWN; #[\Deprecated(since: '8.4', message: "use \\Random\\Randomizer::getFloat() instead")] diff --git a/ext/random/random_arginfo.h b/ext/random/random_arginfo.h index c1cfb8eb34132..0d7ba3c96524b 100644 --- a/ext/random/random_arginfo.h +++ b/ext/random/random_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 8b30f08404f2912d40f4cb61b76ec283af19b79c */ + * Stub hash: 416be19494555016195600e488d79f0dd35f2620 */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_lcg_value, 0, 0, IS_DOUBLE, 0) ZEND_END_ARG_INFO() @@ -240,6 +240,19 @@ static void register_random_symbols(int module_number) 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); attribute_Deprecated_func_lcg_value_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + zend_constant *const_MT_RAND_PHP = zend_hash_str_find_ptr(EG(zend_constants), "MT_RAND_PHP", sizeof("MT_RAND_PHP") - 1); + + 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 attribute_Deprecated_const_MT_RAND_PHP_0_arg0; + zend_string *attribute_Deprecated_const_MT_RAND_PHP_0_arg0_str = zend_string_init("8.3", strlen("8.3"), 1); + ZVAL_STR(&attribute_Deprecated_const_MT_RAND_PHP_0_arg0, attribute_Deprecated_const_MT_RAND_PHP_0_arg0_str); + ZVAL_COPY_VALUE(&attribute_Deprecated_const_MT_RAND_PHP_0->args[0].value, &attribute_Deprecated_const_MT_RAND_PHP_0_arg0); + 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); + attribute_Deprecated_const_MT_RAND_PHP_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); } static zend_class_entry *register_class_Random_Engine_Mt19937(zend_class_entry *class_entry_Random_Engine) diff --git a/ext/random/randomizer.c b/ext/random/randomizer.c index 4f63388e8f56a..fc3c93fc2b053 100644 --- a/ext/random/randomizer.c +++ b/ext/random/randomizer.c @@ -43,16 +43,9 @@ static inline void randomizer_common_init(php_random_randomizer *randomizer, zen .state = state, }; - zend_string *mname; - zend_function *generate_method; - - mname = ZSTR_INIT_LITERAL("generate", 0); - generate_method = zend_hash_find_ptr(&engine_object->ce->function_table, mname); - zend_string_release(mname); - /* Create compatible state */ state->object = engine_object; - state->generate_method = generate_method; + state->generate_method = zend_hash_str_find_ptr(&engine_object->ce->function_table, "generate", strlen("generate")); /* Mark self-allocated for memory management */ randomizer->is_userland_algo = true; @@ -196,7 +189,7 @@ PHP_METHOD(Random_Randomizer, getFloat) RETVAL_DOUBLE(php_random_gammasection_open_open(randomizer->engine, min, max)); if (UNEXPECTED(isnan(Z_DVAL_P(return_value)))) { - zend_value_error("The given interval is empty, there are no floats between argument #1 ($min) and argument #2 ($max)."); + zend_value_error("The given interval is empty, there are no floats between argument #1 ($min) and argument #2 ($max)"); RETURN_THROWS(); } diff --git a/ext/random/tests/01_functions/array_rand_mt_rand_php.phpt b/ext/random/tests/01_functions/array_rand_mt_rand_php.phpt index 703460a890f05..ee3e155484dde 100644 --- a/ext/random/tests/01_functions/array_rand_mt_rand_php.phpt +++ b/ext/random/tests/01_functions/array_rand_mt_rand_php.phpt @@ -24,7 +24,7 @@ var_dump( ); ?> --EXPECTF-- -Deprecated: Constant MT_RAND_PHP is deprecated in %s on line %d +Deprecated: Constant MT_RAND_PHP is deprecated since 8.3, as it uses a biased non-standard variant of Mt19937 in %s on line %d Deprecated: The MT_RAND_PHP variant of Mt19937 is deprecated in %s on line %d string(11) "found key 0" diff --git a/ext/random/tests/01_functions/bug75514.phpt b/ext/random/tests/01_functions/bug75514.phpt index 583ac9a209ef3..8f90064966988 100644 --- a/ext/random/tests/01_functions/bug75514.phpt +++ b/ext/random/tests/01_functions/bug75514.phpt @@ -6,7 +6,7 @@ mt_srand(0, MT_RAND_PHP); var_dump(mt_rand(0,999999999), mt_rand(0,999)); ?> --EXPECTF-- -Deprecated: Constant MT_RAND_PHP is deprecated in %s on line %d +Deprecated: Constant MT_RAND_PHP is deprecated since 8.3, as it uses a biased non-standard variant of Mt19937 in %s on line %d Deprecated: The MT_RAND_PHP variant of Mt19937 is deprecated in %s on line %d int(448865905) diff --git a/ext/random/tests/01_functions/mt_rand_value.phpt b/ext/random/tests/01_functions/mt_rand_value.phpt index ede620648e16b..bf5fdfc2a4e88 100644 --- a/ext/random/tests/01_functions/mt_rand_value.phpt +++ b/ext/random/tests/01_functions/mt_rand_value.phpt @@ -38,7 +38,7 @@ echo $x.PHP_EOL; ?> --EXPECTF-- -Deprecated: Constant MT_RAND_PHP is deprecated in %s on line %d +Deprecated: Constant MT_RAND_PHP is deprecated since 8.3, as it uses a biased non-standard variant of Mt19937 in %s on line %d Deprecated: The MT_RAND_PHP variant of Mt19937 is deprecated in %s on line %d 1614640687 diff --git a/ext/random/tests/03_randomizer/compatibility_mt_rand.phpt b/ext/random/tests/03_randomizer/compatibility_mt_rand.phpt index 4abb1276f3665..50aa7b3efb0d8 100644 --- a/ext/random/tests/03_randomizer/compatibility_mt_rand.phpt +++ b/ext/random/tests/03_randomizer/compatibility_mt_rand.phpt @@ -46,11 +46,11 @@ die('success'); --EXPECTF-- MT_RAND_PHP -Deprecated: Constant MT_RAND_PHP is deprecated in %s on line %d +Deprecated: Constant MT_RAND_PHP is deprecated since 8.3, as it uses a biased non-standard variant of Mt19937 in %s on line %d Deprecated: The MT_RAND_PHP variant of Mt19937 is deprecated in %s on line %d -Deprecated: Constant MT_RAND_PHP is deprecated in %s on line %d +Deprecated: Constant MT_RAND_PHP is deprecated since 8.3, as it uses a biased non-standard variant of Mt19937 in %s on line %d Deprecated: The MT_RAND_PHP variant of Mt19937 is deprecated in %s on line %d MT_RAND_MT19937 diff --git a/ext/random/tests/03_randomizer/methods/getBytes.phpt b/ext/random/tests/03_randomizer/methods/getBytes.phpt index 70aca6e22f8b6..2a163040ac770 100644 --- a/ext/random/tests/03_randomizer/methods/getBytes.phpt +++ b/ext/random/tests/03_randomizer/methods/getBytes.phpt @@ -39,7 +39,7 @@ die('success'); ?> --EXPECTF-- -Deprecated: Constant MT_RAND_PHP is deprecated in %s on line %d +Deprecated: Constant MT_RAND_PHP is deprecated since 8.3, as it uses a biased non-standard variant of Mt19937 in %s on line %d Deprecated: The MT_RAND_PHP variant of Mt19937 is deprecated in %s on line %d Random\Engine\Mt19937 diff --git a/ext/random/tests/03_randomizer/methods/getBytesFromString.phpt b/ext/random/tests/03_randomizer/methods/getBytesFromString.phpt index 06d24cc82bd23..8189d061d9701 100644 --- a/ext/random/tests/03_randomizer/methods/getBytesFromString.phpt +++ b/ext/random/tests/03_randomizer/methods/getBytesFromString.phpt @@ -43,7 +43,7 @@ die('success'); ?> --EXPECTF-- -Deprecated: Constant MT_RAND_PHP is deprecated in %s on line %d +Deprecated: Constant MT_RAND_PHP is deprecated since 8.3, as it uses a biased non-standard variant of Mt19937 in %s on line %d Deprecated: The MT_RAND_PHP variant of Mt19937 is deprecated in %s on line %d Random\Engine\Mt19937 diff --git a/ext/random/tests/03_randomizer/methods/getFloat.phpt b/ext/random/tests/03_randomizer/methods/getFloat.phpt index 8655777f89c3a..c07fedcc210e4 100644 --- a/ext/random/tests/03_randomizer/methods/getFloat.phpt +++ b/ext/random/tests/03_randomizer/methods/getFloat.phpt @@ -42,7 +42,7 @@ die('success'); ?> --EXPECTF-- -Deprecated: Constant MT_RAND_PHP is deprecated in %s on line %d +Deprecated: Constant MT_RAND_PHP is deprecated since 8.3, as it uses a biased non-standard variant of Mt19937 in %s on line %d Deprecated: The MT_RAND_PHP variant of Mt19937 is deprecated in %s on line %d Random\Engine\Mt19937 diff --git a/ext/random/tests/03_randomizer/methods/getFloat_error.phpt b/ext/random/tests/03_randomizer/methods/getFloat_error.phpt index 286435e1752fb..42e933cbefb29 100644 --- a/ext/random/tests/03_randomizer/methods/getFloat_error.phpt +++ b/ext/random/tests/03_randomizer/methods/getFloat_error.phpt @@ -127,4 +127,4 @@ Random\Randomizer::getFloat(): Argument #2 ($max) must be finite Random\Randomizer::getFloat(): Argument #2 ($max) must be greater than argument #1 ($min) Random\Randomizer::getFloat(): Argument #2 ($max) must be greater than argument #1 ($min) Random\Randomizer::getFloat(): Argument #2 ($max) must be greater than argument #1 ($min) -The given interval is empty, there are no floats between argument #1 ($min) and argument #2 ($max). +The given interval is empty, there are no floats between argument #1 ($min) and argument #2 ($max) diff --git a/ext/random/tests/03_randomizer/methods/getInt.phpt b/ext/random/tests/03_randomizer/methods/getInt.phpt index ba936dcf3bf0f..5f1656c615a7f 100644 --- a/ext/random/tests/03_randomizer/methods/getInt.phpt +++ b/ext/random/tests/03_randomizer/methods/getInt.phpt @@ -46,7 +46,7 @@ die('success'); ?> --EXPECTF-- -Deprecated: Constant MT_RAND_PHP is deprecated in %s on line %d +Deprecated: Constant MT_RAND_PHP is deprecated since 8.3, as it uses a biased non-standard variant of Mt19937 in %s on line %d Deprecated: The MT_RAND_PHP variant of Mt19937 is deprecated in %s on line %d Random\Engine\Mt19937 diff --git a/ext/random/tests/03_randomizer/methods/nextFloat.phpt b/ext/random/tests/03_randomizer/methods/nextFloat.phpt index b515242137506..62243faf434a7 100644 --- a/ext/random/tests/03_randomizer/methods/nextFloat.phpt +++ b/ext/random/tests/03_randomizer/methods/nextFloat.phpt @@ -41,7 +41,7 @@ die('success'); ?> --EXPECTF-- -Deprecated: Constant MT_RAND_PHP is deprecated in %s on line %d +Deprecated: Constant MT_RAND_PHP is deprecated since 8.3, as it uses a biased non-standard variant of Mt19937 in %s on line %d Deprecated: The MT_RAND_PHP variant of Mt19937 is deprecated in %s on line %d Random\Engine\Mt19937 diff --git a/ext/random/tests/03_randomizer/methods/nextInt.phpt b/ext/random/tests/03_randomizer/methods/nextInt.phpt index 008e5acb259e8..6739ae9f1cf55 100644 --- a/ext/random/tests/03_randomizer/methods/nextInt.phpt +++ b/ext/random/tests/03_randomizer/methods/nextInt.phpt @@ -41,7 +41,7 @@ die('success'); ?> --EXPECTF-- -Deprecated: Constant MT_RAND_PHP is deprecated in %s on line %d +Deprecated: Constant MT_RAND_PHP is deprecated since 8.3, as it uses a biased non-standard variant of Mt19937 in %s on line %d Deprecated: The MT_RAND_PHP variant of Mt19937 is deprecated in %s on line %d Random\Engine\Mt19937 diff --git a/ext/random/tests/03_randomizer/methods/pickArrayKeys.phpt b/ext/random/tests/03_randomizer/methods/pickArrayKeys.phpt index d5b159f2af136..8c799909c8749 100644 --- a/ext/random/tests/03_randomizer/methods/pickArrayKeys.phpt +++ b/ext/random/tests/03_randomizer/methods/pickArrayKeys.phpt @@ -76,7 +76,7 @@ die('success'); ?> --EXPECTF-- -Deprecated: Constant MT_RAND_PHP is deprecated in %s on line %d +Deprecated: Constant MT_RAND_PHP is deprecated since 8.3, as it uses a biased non-standard variant of Mt19937 in %s on line %d Deprecated: The MT_RAND_PHP variant of Mt19937 is deprecated in %s on line %d Random\Engine\Mt19937 diff --git a/ext/random/tests/03_randomizer/methods/shuffleArray.phpt b/ext/random/tests/03_randomizer/methods/shuffleArray.phpt index af4ce88b3821d..302e683edbf20 100644 --- a/ext/random/tests/03_randomizer/methods/shuffleArray.phpt +++ b/ext/random/tests/03_randomizer/methods/shuffleArray.phpt @@ -45,7 +45,7 @@ die('success'); ?> --EXPECTF-- -Deprecated: Constant MT_RAND_PHP is deprecated in %s on line %d +Deprecated: Constant MT_RAND_PHP is deprecated since 8.3, as it uses a biased non-standard variant of Mt19937 in %s on line %d Deprecated: The MT_RAND_PHP variant of Mt19937 is deprecated in %s on line %d Random\Engine\Mt19937 diff --git a/ext/random/tests/03_randomizer/methods/shuffleBytes.phpt b/ext/random/tests/03_randomizer/methods/shuffleBytes.phpt index 404b670e2863a..cacf3688bb310 100644 --- a/ext/random/tests/03_randomizer/methods/shuffleBytes.phpt +++ b/ext/random/tests/03_randomizer/methods/shuffleBytes.phpt @@ -52,7 +52,7 @@ die('success'); ?> --EXPECTF-- -Deprecated: Constant MT_RAND_PHP is deprecated in %s on line %d +Deprecated: Constant MT_RAND_PHP is deprecated since 8.3, as it uses a biased non-standard variant of Mt19937 in %s on line %d Deprecated: The MT_RAND_PHP variant of Mt19937 is deprecated in %s on line %d Random\Engine\Mt19937 diff --git a/ext/random/tests/03_randomizer/serialize.phpt b/ext/random/tests/03_randomizer/serialize.phpt index 1f56228d33220..4ac8bfe6e682a 100644 --- a/ext/random/tests/03_randomizer/serialize.phpt +++ b/ext/random/tests/03_randomizer/serialize.phpt @@ -43,7 +43,7 @@ foreach ($engines as $engine) { die('success'); ?> --EXPECTF-- -Deprecated: Constant MT_RAND_PHP is deprecated in %s on line %d +Deprecated: Constant MT_RAND_PHP is deprecated since 8.3, as it uses a biased non-standard variant of Mt19937 in %s on line %d Deprecated: The MT_RAND_PHP variant of Mt19937 is deprecated in %s on line %d Random\Engine\Mt19937 diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index 8ef0269481cf7..78817152904fb 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -2844,7 +2844,7 @@ ZEND_METHOD(ReflectionParameter, isCallable) } /* }}} */ -/* {{{ Returns whether NULL is allowed as this parameters's value */ +/* {{{ Returns whether NULL is allowed as this parameter's value */ ZEND_METHOD(ReflectionParameter, allowsNull) { reflection_object *intern; diff --git a/ext/reflection/tests/internal_parameter_default_value/check_all.phpt b/ext/reflection/tests/internal_parameter_default_value/check_all.phpt index 534f781c4fc1a..241dea449b615 100644 --- a/ext/reflection/tests/internal_parameter_default_value/check_all.phpt +++ b/ext/reflection/tests/internal_parameter_default_value/check_all.phpt @@ -30,7 +30,7 @@ foreach (get_declared_classes() as $class) { ?> ===DONE=== --EXPECTF-- -Deprecated: Constant SUNFUNCS_RET_STRING is deprecated in %s on line %d +Deprecated: Constant SUNFUNCS_RET_STRING is deprecated since 8.4, as date_sunrise() and date_sunset() were deprecated in 8.1 in %s on line %d -Deprecated: Constant SUNFUNCS_RET_STRING is deprecated in %s on line %d +Deprecated: Constant SUNFUNCS_RET_STRING is deprecated since 8.4, as date_sunrise() and date_sunset() were deprecated in 8.1 in %s on line %d ===DONE=== diff --git a/ext/soap/php_http.c b/ext/soap/php_http.c index 84a10368d22fe..2d6ed207efbdd 100644 --- a/ext/soap/php_http.c +++ b/ext/soap/php_http.c @@ -506,10 +506,10 @@ int make_http_soap_request(zval *this_ptr, zend_string_equals(orig->host, phpurl->host) && orig->port == phpurl->port))) { } else { + ZVAL_NULL(Z_CLIENT_HTTPSOCKET_P(this_ptr)); php_stream_close(stream); convert_to_null(Z_CLIENT_HTTPURL_P(this_ptr)); - convert_to_null(Z_CLIENT_HTTPSOCKET_P(this_ptr)); - convert_to_null(Z_CLIENT_USE_PROXY_P(this_ptr)); + ZVAL_NULL(Z_CLIENT_USE_PROXY_P(this_ptr)); stream = NULL; use_proxy = 0; } @@ -517,10 +517,10 @@ int make_http_soap_request(zval *this_ptr, /* Check if keep-alive connection is still opened */ if (stream != NULL && php_stream_eof(stream)) { + ZVAL_NULL(Z_CLIENT_HTTPSOCKET_P(this_ptr)); php_stream_close(stream); convert_to_null(Z_CLIENT_HTTPURL_P(this_ptr)); - convert_to_null(Z_CLIENT_HTTPSOCKET_P(this_ptr)); - convert_to_null(Z_CLIENT_USE_PROXY_P(this_ptr)); + ZVAL_NULL(Z_CLIENT_USE_PROXY_P(this_ptr)); stream = NULL; use_proxy = 0; } @@ -528,9 +528,7 @@ int make_http_soap_request(zval *this_ptr, if (!stream) { stream = http_connect(this_ptr, phpurl, use_ssl, context, &use_proxy); if (stream) { - php_stream_auto_cleanup(stream); - ZVAL_RES(Z_CLIENT_HTTPSOCKET_P(this_ptr), stream->res); - GC_ADDREF(stream->res); + php_stream_to_zval(stream, Z_CLIENT_HTTPSOCKET_P(this_ptr)); ZVAL_LONG(Z_CLIENT_USE_PROXY_P(this_ptr), use_proxy); } else { php_url_free(phpurl); @@ -686,10 +684,10 @@ int make_http_soap_request(zval *this_ptr, if (UNEXPECTED(php_random_bytes_throw(&nonce, sizeof(nonce)) != SUCCESS)) { ZEND_ASSERT(EG(exception)); + ZVAL_NULL(Z_CLIENT_HTTPSOCKET_P(this_ptr)); php_stream_close(stream); convert_to_null(Z_CLIENT_HTTPURL_P(this_ptr)); - convert_to_null(Z_CLIENT_HTTPSOCKET_P(this_ptr)); - convert_to_null(Z_CLIENT_USE_PROXY_P(this_ptr)); + ZVAL_NULL(Z_CLIENT_USE_PROXY_P(this_ptr)); smart_str_free(&soap_headers_z); smart_str_free(&soap_headers); efree(http_msg); @@ -904,10 +902,10 @@ int make_http_soap_request(zval *this_ptr, if (request != buf) { zend_string_release_ex(request, 0); } + ZVAL_NULL(Z_CLIENT_HTTPSOCKET_P(this_ptr)); php_stream_close(stream); convert_to_null(Z_CLIENT_HTTPURL_P(this_ptr)); - convert_to_null(Z_CLIENT_HTTPSOCKET_P(this_ptr)); - convert_to_null(Z_CLIENT_USE_PROXY_P(this_ptr)); + ZVAL_NULL(Z_CLIENT_USE_PROXY_P(this_ptr)); add_soap_fault(this_ptr, "HTTP", "Failed Sending HTTP SOAP request", NULL, NULL, SOAP_GLOBAL(lang_en)); smart_str_free(&soap_headers_z); efree(http_msg); @@ -929,9 +927,9 @@ int make_http_soap_request(zval *this_ptr, if (request != buf) { zend_string_release_ex(request, 0); } + ZVAL_NULL(Z_CLIENT_HTTPSOCKET_P(this_ptr)); php_stream_close(stream); - convert_to_null(Z_CLIENT_HTTPSOCKET_P(this_ptr)); - convert_to_null(Z_CLIENT_USE_PROXY_P(this_ptr)); + ZVAL_NULL(Z_CLIENT_USE_PROXY_P(this_ptr)); add_soap_fault(this_ptr, "HTTP", "Error Fetching http headers", NULL, NULL, SOAP_GLOBAL(lang_en)); smart_str_free(&soap_headers_z); efree(http_msg); @@ -982,12 +980,12 @@ int make_http_soap_request(zval *this_ptr, if (request != buf) { zend_string_release_ex(request, 0); } + ZVAL_NULL(Z_CLIENT_HTTPSOCKET_P(this_ptr)); php_stream_close(stream); if (http_headers) { zend_string_release_ex(http_headers, 0); } - convert_to_null(Z_CLIENT_HTTPSOCKET_P(this_ptr)); - convert_to_null(Z_CLIENT_USE_PROXY_P(this_ptr)); + ZVAL_NULL(Z_CLIENT_USE_PROXY_P(this_ptr)); if (http_msg) { efree(http_msg); } @@ -1117,10 +1115,10 @@ int make_http_soap_request(zval *this_ptr, if (request != buf) { zend_string_release_ex(request, 0); } + ZVAL_NULL(Z_CLIENT_HTTPSOCKET_P(this_ptr)); php_stream_close(stream); zend_string_release_ex(http_headers, 0); - convert_to_null(Z_CLIENT_HTTPSOCKET_P(this_ptr)); - convert_to_null(Z_CLIENT_USE_PROXY_P(this_ptr)); + ZVAL_NULL(Z_CLIENT_USE_PROXY_P(this_ptr)); add_soap_fault(this_ptr, "HTTP", "Error Fetching http body, No Content-Length, connection closed or chunked data", NULL, NULL, SOAP_GLOBAL(lang_en)); if (http_msg) { efree(http_msg); @@ -1134,9 +1132,9 @@ int make_http_soap_request(zval *this_ptr, } if (http_close) { + ZVAL_NULL(Z_CLIENT_HTTPSOCKET_P(this_ptr)); php_stream_close(stream); - convert_to_null(Z_CLIENT_HTTPSOCKET_P(this_ptr)); - convert_to_null(Z_CLIENT_USE_PROXY_P(this_ptr)); + ZVAL_NULL(Z_CLIENT_USE_PROXY_P(this_ptr)); stream = NULL; } @@ -1296,21 +1294,19 @@ int make_http_soap_request(zval *this_ptr, /* Decompress response */ content_encoding = get_http_header_value(ZSTR_VAL(http_headers), "Content-Encoding:"); if (content_encoding) { - zval func; zval retval; zval params[1]; + zend_function *decompression_fn; /* Warning: the zlib function names are chosen in an unfortunate manner. * Check zlib.c to see how a function corresponds with a particular format. */ if ((strcmp(content_encoding,"gzip") == 0 || strcmp(content_encoding,"x-gzip") == 0) && - zend_hash_str_exists(EG(function_table), "gzdecode", sizeof("gzdecode")-1)) { - ZVAL_STRING(&func, "gzdecode"); - ZVAL_STR_COPY(¶ms[0], http_body); + (decompression_fn = zend_hash_str_find_ptr(EG(function_table), "gzdecode", sizeof("gzdecode")-1))) { + ZVAL_STR(¶ms[0], http_body); } else if (strcmp(content_encoding,"deflate") == 0 && - zend_hash_str_exists(EG(function_table), "gzuncompress", sizeof("gzuncompress")-1)) { - ZVAL_STRING(&func, "gzuncompress"); - ZVAL_STR_COPY(¶ms[0], http_body); + (decompression_fn = zend_hash_str_find_ptr(EG(function_table), "gzuncompress", sizeof("gzuncompress")-1))) { + ZVAL_STR(¶ms[0], http_body); } else { efree(content_encoding); zend_string_release_ex(http_headers, 0); @@ -1321,15 +1317,11 @@ int make_http_soap_request(zval *this_ptr, add_soap_fault(this_ptr, "HTTP", "Unknown Content-Encoding", NULL, NULL, SOAP_GLOBAL(lang_en)); return FALSE; } - if (call_user_function(CG(function_table), (zval*)NULL, &func, &retval, 1, params) == SUCCESS && - Z_TYPE(retval) == IS_STRING) { - zval_ptr_dtor(¶ms[0]); - zval_ptr_dtor(&func); + zend_call_known_function(decompression_fn, NULL, NULL, &retval, 1, params, NULL); + if (Z_TYPE(retval) == IS_STRING) { zend_string_release_ex(http_body, 0); ZVAL_COPY_VALUE(return_value, &retval); } else { - zval_ptr_dtor(¶ms[0]); - zval_ptr_dtor(&func); zval_ptr_dtor(&retval); efree(content_encoding); zend_string_release_ex(http_headers, 0); diff --git a/ext/soap/php_soap.h b/ext/soap/php_soap.h index 98e3d4af6f19d..1eea30c62e905 100644 --- a/ext/soap/php_soap.h +++ b/ext/soap/php_soap.h @@ -216,42 +216,43 @@ static zend_always_inline zval *php_soap_deref(zval *zv) { return zv; } -#define Z_CLIENT_URI_P(zv) php_soap_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 0)) -#define Z_CLIENT_STYLE_P(zv) php_soap_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 1)) -#define Z_CLIENT_USE_P(zv) php_soap_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 2)) -#define Z_CLIENT_LOCATION_P(zv) php_soap_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 3)) -#define Z_CLIENT_TRACE_P(zv) php_soap_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 4)) -#define Z_CLIENT_COMPRESSION_P(zv) php_soap_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 5)) -#define Z_CLIENT_SDL_P(zv) php_soap_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 6)) -#define Z_CLIENT_TYPEMAP_P(zv) php_soap_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 7)) -#define Z_CLIENT_HTTPSOCKET_P(zv) php_soap_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 8)) -#define Z_CLIENT_HTTPURL_P(zv) php_soap_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 9)) -#define Z_CLIENT_LOGIN_P(zv) php_soap_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 10)) -#define Z_CLIENT_PASSWORD_P(zv) php_soap_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 11)) -#define Z_CLIENT_USE_DIGEST_P(zv) php_soap_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 12)) -#define Z_CLIENT_DIGEST_P(zv) php_soap_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 13)) -#define Z_CLIENT_PROXY_HOST_P(zv) php_soap_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 14)) -#define Z_CLIENT_PROXY_PORT_P(zv) php_soap_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 15)) -#define Z_CLIENT_PROXY_LOGIN_P(zv) php_soap_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 16)) -#define Z_CLIENT_PROXY_PASSWORD_P(zv) php_soap_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 17)) -#define Z_CLIENT_EXCEPTIONS_P(zv) php_soap_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 18)) -#define Z_CLIENT_ENCODING_P(zv) php_soap_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 19)) -#define Z_CLIENT_CLASSMAP_P(zv) php_soap_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 20)) -#define Z_CLIENT_FEATURES_P(zv) php_soap_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 21)) -#define Z_CLIENT_CONNECTION_TIMEOUT_P(zv) php_soap_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 22)) -#define Z_CLIENT_STREAM_CONTEXT_P(zv) php_soap_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 23)) -#define Z_CLIENT_USER_AGENT_P(zv) php_soap_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 24)) -#define Z_CLIENT_KEEP_ALIVE_P(zv) php_soap_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 25)) -#define Z_CLIENT_SSL_METHOD_P(zv) php_soap_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 26)) -#define Z_CLIENT_SOAP_VERSION_P(zv) php_soap_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 27)) -#define Z_CLIENT_USE_PROXY_P(zv) php_soap_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 28)) -#define Z_CLIENT_COOKIES_P(zv) php_soap_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 29)) -#define Z_CLIENT_DEFAULT_HEADERS_P(zv) php_soap_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 30)) -#define Z_CLIENT_SOAP_FAULT_P(zv) php_soap_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 31)) -#define Z_CLIENT_LAST_REQUEST_P(zv) php_soap_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 32)) -#define Z_CLIENT_LAST_RESPONSE_P(zv) php_soap_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 33)) -#define Z_CLIENT_LAST_REQUEST_HEADERS_P(zv) php_soap_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 34)) -#define Z_CLIENT_LAST_RESPONSE_HEADERS_P(zv) php_soap_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 35)) +/* SoapClient's properties are all private and can't be references */ +#define Z_CLIENT_URI_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 0) +#define Z_CLIENT_STYLE_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 1) +#define Z_CLIENT_USE_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 2) +#define Z_CLIENT_LOCATION_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 3) +#define Z_CLIENT_TRACE_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 4) +#define Z_CLIENT_COMPRESSION_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 5) +#define Z_CLIENT_SDL_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 6) +#define Z_CLIENT_TYPEMAP_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 7) +#define Z_CLIENT_HTTPSOCKET_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 8) +#define Z_CLIENT_HTTPURL_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 9) +#define Z_CLIENT_LOGIN_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 10) +#define Z_CLIENT_PASSWORD_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 11) +#define Z_CLIENT_USE_DIGEST_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 12) +#define Z_CLIENT_DIGEST_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 13) +#define Z_CLIENT_PROXY_HOST_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 14) +#define Z_CLIENT_PROXY_PORT_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 15) +#define Z_CLIENT_PROXY_LOGIN_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 16) +#define Z_CLIENT_PROXY_PASSWORD_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 17) +#define Z_CLIENT_EXCEPTIONS_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 18) +#define Z_CLIENT_ENCODING_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 19) +#define Z_CLIENT_CLASSMAP_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 20) +#define Z_CLIENT_FEATURES_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 21) +#define Z_CLIENT_CONNECTION_TIMEOUT_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 22) +#define Z_CLIENT_STREAM_CONTEXT_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 23) +#define Z_CLIENT_USER_AGENT_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 24) +#define Z_CLIENT_KEEP_ALIVE_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 25) +#define Z_CLIENT_SSL_METHOD_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 26) +#define Z_CLIENT_SOAP_VERSION_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 27) +#define Z_CLIENT_USE_PROXY_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 28) +#define Z_CLIENT_COOKIES_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 29) +#define Z_CLIENT_DEFAULT_HEADERS_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 30) +#define Z_CLIENT_SOAP_FAULT_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 31) +#define Z_CLIENT_LAST_REQUEST_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 32) +#define Z_CLIENT_LAST_RESPONSE_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 33) +#define Z_CLIENT_LAST_REQUEST_HEADERS_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 34) +#define Z_CLIENT_LAST_RESPONSE_HEADERS_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 35) typedef struct soap_url_object { php_url *url; diff --git a/ext/soap/soap.c b/ext/soap/soap.c index cdb0216ebcf83..0786ac811059e 100644 --- a/ext/soap/soap.c +++ b/ext/soap/soap.c @@ -21,6 +21,7 @@ #endif #include "php_soap.h" #include "ext/session/php_session.h" +#include "zend_attributes.h" #include "soap_arginfo.h" #include "zend_exceptions.h" #include "zend_interfaces.h" @@ -4204,8 +4205,10 @@ static xmlNodePtr serialize_zval(zval *val, sdlParamPtr param, const char *param } xmlParam = master_to_xml(enc, val, style, parent); zval_ptr_dtor(&defval); - if (!strcmp((char*)xmlParam->name, "BOGUS")) { - xmlNodeSetName(xmlParam, BAD_CAST(paramName)); + if (xmlParam != NULL) { + if (xmlParam->name == NULL || strcmp((char*)xmlParam->name, "BOGUS") == 0) { + xmlNodeSetName(xmlParam, BAD_CAST(paramName)); + } } return xmlParam; } diff --git a/ext/soap/soap.stub.php b/ext/soap/soap.stub.php index 2520bd1346963..15d4ef1e6bd3e 100644 --- a/ext/soap/soap.stub.php +++ b/ext/soap/soap.stub.php @@ -44,8 +44,8 @@ final class Sdl /** * @var int * @cvalue SOAP_FUNCTIONS_ALL - * @deprecated since 8.4 */ + #[\Deprecated(since: '8.4', message: 'as enabling all functions is a possible security concern')] const SOAP_FUNCTIONS_ALL = UNKNOWN; /** diff --git a/ext/soap/soap_arginfo.h b/ext/soap/soap_arginfo.h index e932f2af71093..c4ce5bf1e58b7 100644 --- a/ext/soap/soap_arginfo.h +++ b/ext/soap/soap_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 78a27b18c6b4007494a6aed9acc5f6e99c6f0350 */ + * Stub hash: 4277993645a3f560c7a9971466fabf2d451bc92d */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_use_soap_error_handler, 0, 0, _IS_BOOL, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, enable, _IS_BOOL, 0, "true") @@ -315,6 +315,20 @@ static void register_soap_symbols(int module_number) REGISTER_LONG_CONSTANT("SOAP_SSL_METHOD_SSLv2", SOAP_SSL_METHOD_SSLv2, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("SOAP_SSL_METHOD_SSLv3", SOAP_SSL_METHOD_SSLv3, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("SOAP_SSL_METHOD_SSLv23", SOAP_SSL_METHOD_SSLv23, CONST_PERSISTENT); + + zend_constant *const_SOAP_FUNCTIONS_ALL = zend_hash_str_find_ptr(EG(zend_constants), "SOAP_FUNCTIONS_ALL", sizeof("SOAP_FUNCTIONS_ALL") - 1); + + 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 attribute_Deprecated_const_SOAP_FUNCTIONS_ALL_0_arg0; + zend_string *attribute_Deprecated_const_SOAP_FUNCTIONS_ALL_0_arg0_str = zend_string_init("8.4", strlen("8.4"), 1); + ZVAL_STR(&attribute_Deprecated_const_SOAP_FUNCTIONS_ALL_0_arg0, attribute_Deprecated_const_SOAP_FUNCTIONS_ALL_0_arg0_str); + ZVAL_COPY_VALUE(&attribute_Deprecated_const_SOAP_FUNCTIONS_ALL_0->args[0].value, &attribute_Deprecated_const_SOAP_FUNCTIONS_ALL_0_arg0); + 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); + attribute_Deprecated_const_SOAP_FUNCTIONS_ALL_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); } static zend_class_entry *register_class_Soap_Url(void) diff --git a/ext/soap/tests/bugs/gh18990.phpt b/ext/soap/tests/bugs/gh18990.phpt new file mode 100644 index 0000000000000..30dbc0fe8b751 --- /dev/null +++ b/ext/soap/tests/bugs/gh18990.phpt @@ -0,0 +1,58 @@ +--TEST-- +GH-18990 (SOAP HTTP socket not closing on object destruction) +--INI-- +soap.wsdl_cache_enabled=0 +--EXTENSIONS-- +soap +--SKIPIF-- + +text0text1text2text3text4text5text6text7text8text9 +EOF; + +$responses = [ + "data://text/plain,HTTP/1.1 200 OK\r\n". + "Content-Type: text/xml;charset=utf-8\r\n". + "Connection: Keep-Alive\r\n". + "Content-Length: ".strlen($wsdl)."\r\n". + "\r\n". + $wsdl, + + "data://text/plain,HTTP/1.1 200 OK\r\n". + "Content-Type: text/xml;charset=utf-8\r\n". + "Connection: Keep-Alive\r\n". + "Content-Length: ".strlen($soap)."\r\n". + "\r\n". + $soap, +]; + +['pid' => $pid, 'uri' => $uri] = http_server($responses); + +$options = [ + 'trace' => false, + 'location' => $uri, +]; + +$cnt = count(get_resources()); + +$client = new SoapClient($uri, $options); + +var_dump(count($client->getItems())); + +http_server_kill($pid); + +unset($client); +var_dump(count(get_resources()) - $cnt); +?> +--EXPECT-- +int(10) +int(0) diff --git a/ext/soap/tests/server003.phpt b/ext/soap/tests/server003.phpt index 1425daf819404..c278ca23a1959 100644 --- a/ext/soap/tests/server003.phpt +++ b/ext/soap/tests/server003.phpt @@ -27,7 +27,7 @@ $server->handle($HTTP_RAW_POST_DATA); echo "ok\n"; ?> --EXPECTF-- -Deprecated: Constant SOAP_FUNCTIONS_ALL is deprecated in %s on line %d +Deprecated: Constant SOAP_FUNCTIONS_ALL is deprecated since 8.4, as enabling all functions is a possible security concern in %s on line %d Deprecated: SoapServer::addFunction(): Enabling all functions via SOAP_FUNCTIONS_ALL is deprecated since 8.4, due to possible security concerns. If all PHP functions should be enabled, the flattened return value of get_defined_functions() can be used in %s on line %d diff --git a/ext/soap/tests/soap_qname_crash.phpt b/ext/soap/tests/soap_qname_crash.phpt new file mode 100644 index 0000000000000..bcf01d574fab4 --- /dev/null +++ b/ext/soap/tests/soap_qname_crash.phpt @@ -0,0 +1,48 @@ +--TEST-- +Test SoapClient with excessively large QName prefix in SoapVar +--EXTENSIONS-- +soap +--SKIPIF-- + +--INI-- +memory_limit=6144M +--FILE-- + 'http://127.0.0.1/', + 'uri' => 'urn:dummy', + 'trace' => 1, + 'exceptions' => true, +]; +$client = new TestSoapClient(null, $options); +$client->__soapCall("DummyFunction", [$var]); +?> +--EXPECT-- +Attempting to create SoapVar with very large QName +Attempting encoding + +value diff --git a/ext/spl/spl_array.c b/ext/spl/spl_array.c index b950330061920..5cb3e27bbb861 100644 --- a/ext/spl/spl_array.c +++ b/ext/spl/spl_array.c @@ -1203,43 +1203,54 @@ PHP_METHOD(ArrayObject, count) RETURN_LONG(spl_array_object_count_elements_helper(intern)); } /* }}} */ -static void spl_array_method(INTERNAL_FUNCTION_PARAMETERS, char *fname, size_t fname_len, int use_arg) /* {{{ */ +enum spl_array_object_sort_methods { + SPL_NAT_SORT, + SPL_CALLBACK_SORT, + SPL_OPTIONAL_FLAG_SORT +}; + +static void spl_array_method(INTERNAL_FUNCTION_PARAMETERS, const char *fname, size_t fname_len, enum spl_array_object_sort_methods use_arg) /* {{{ */ { spl_array_object *intern = Z_SPLARRAY_P(ZEND_THIS); HashTable **ht_ptr = spl_array_get_hash_table_ptr(intern); HashTable *aht = *ht_ptr; - zval function_name, params[2], *arg = NULL; + zval params[2], *arg = NULL; - ZVAL_STRINGL(&function_name, fname, fname_len); + zend_function *fn = zend_hash_str_find_ptr(EG(function_table), fname, fname_len); + if (UNEXPECTED(fn == NULL)) { + zend_throw_error(NULL, "Cannot call method %s when function %s is disabled", fname, fname); + RETURN_THROWS(); + } ZVAL_NEW_EMPTY_REF(¶ms[0]); ZVAL_ARR(Z_REFVAL(params[0]), aht); GC_ADDREF(aht); - if (!use_arg) { + if (use_arg == SPL_NAT_SORT) { if (zend_parse_parameters_none() == FAILURE) { goto exit; } intern->nApplyCount++; - call_user_function(EG(function_table), NULL, &function_name, return_value, 1, params); + zend_call_known_function(fn, NULL, NULL, return_value, 1, params, NULL); intern->nApplyCount--; - } else if (use_arg == SPL_ARRAY_METHOD_SORT_FLAGS_ARG) { + } else if (use_arg == SPL_OPTIONAL_FLAG_SORT) { zend_long sort_flags = 0; if (zend_parse_parameters(ZEND_NUM_ARGS(), "|l", &sort_flags) == FAILURE) { goto exit; } ZVAL_LONG(¶ms[1], sort_flags); intern->nApplyCount++; - call_user_function(EG(function_table), NULL, &function_name, return_value, 2, params); + zend_call_known_function(fn, NULL, NULL, return_value, 2, params, NULL); intern->nApplyCount--; } else { + ZEND_ASSERT(use_arg == SPL_CALLBACK_SORT); if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &arg) == FAILURE) { goto exit; } ZVAL_COPY_VALUE(¶ms[1], arg); intern->nApplyCount++; - call_user_function(EG(function_table), NULL, &function_name, return_value, 2, params); + zend_call_known_function(fn, NULL, NULL, return_value, 2, params, NULL); intern->nApplyCount--; } @@ -1251,7 +1262,6 @@ static void spl_array_method(INTERNAL_FUNCTION_PARAMETERS, char *fname, size_t f *ht_ptr = Z_ARRVAL_P(ht_zv); ZVAL_NULL(ht_zv); zval_ptr_dtor(¶ms[0]); - zend_string_free(Z_STR(function_name)); } } /* }}} */ @@ -1261,23 +1271,23 @@ PHP_METHOD(cname, fname) \ spl_array_method(INTERNAL_FUNCTION_PARAM_PASSTHRU, #fname, sizeof(#fname)-1, use_arg); \ } -/* {{{ Sort the entries by values. */ -SPL_ARRAY_METHOD(ArrayObject, asort, SPL_ARRAY_METHOD_SORT_FLAGS_ARG) /* }}} */ +/* Sort the entries by values. */ +SPL_ARRAY_METHOD(ArrayObject, asort, SPL_OPTIONAL_FLAG_SORT) -/* {{{ Sort the entries by key. */ -SPL_ARRAY_METHOD(ArrayObject, ksort, SPL_ARRAY_METHOD_SORT_FLAGS_ARG) /* }}} */ +/* Sort the entries by key. */ +SPL_ARRAY_METHOD(ArrayObject, ksort, SPL_OPTIONAL_FLAG_SORT) -/* {{{ Sort the entries by values user defined function. */ -SPL_ARRAY_METHOD(ArrayObject, uasort, SPL_ARRAY_METHOD_CALLBACK_ARG) /* }}} */ +/* Sort the entries by values user defined function. */ +SPL_ARRAY_METHOD(ArrayObject, uasort, SPL_CALLBACK_SORT) -/* {{{ Sort the entries by key using user defined function. */ -SPL_ARRAY_METHOD(ArrayObject, uksort, SPL_ARRAY_METHOD_CALLBACK_ARG) /* }}} */ +/* Sort the entries by key using user defined function. */ +SPL_ARRAY_METHOD(ArrayObject, uksort, SPL_CALLBACK_SORT) -/* {{{ Sort the entries by values using "natural order" algorithm. */ -SPL_ARRAY_METHOD(ArrayObject, natsort, SPL_ARRAY_METHOD_NO_ARG) /* }}} */ +/* Sort the entries by values using "natural order" algorithm. */ +SPL_ARRAY_METHOD(ArrayObject, natsort, SPL_NAT_SORT) -/* {{{ Sort the entries by key using case insensitive "natural order" algorithm. */ -SPL_ARRAY_METHOD(ArrayObject, natcasesort, SPL_ARRAY_METHOD_NO_ARG) /* }}} */ +/* {{{ Sort the entries by key using case-insensitive "natural order" algorithm. */ +SPL_ARRAY_METHOD(ArrayObject, natcasesort, SPL_NAT_SORT) /* {{{ Serialize the object */ PHP_METHOD(ArrayObject, serialize) diff --git a/ext/spl/spl_array.h b/ext/spl/spl_array.h index f3577f4beeaad..86de7a955c5b2 100644 --- a/ext/spl/spl_array.h +++ b/ext/spl/spl_array.h @@ -27,10 +27,6 @@ #define SPL_ARRAY_INT_MASK 0xFFFF0000 #define SPL_ARRAY_CLONE_MASK 0x0100FFFF -#define SPL_ARRAY_METHOD_NO_ARG 0 -#define SPL_ARRAY_METHOD_CALLBACK_ARG 1 -#define SPL_ARRAY_METHOD_SORT_FLAGS_ARG 2 - extern PHPAPI zend_class_entry *spl_ce_ArrayObject; extern PHPAPI zend_class_entry *spl_ce_ArrayIterator; extern PHPAPI zend_class_entry *spl_ce_RecursiveArrayIterator; diff --git a/ext/spl/tests/ArrayObject/asort_disabled.phpt b/ext/spl/tests/ArrayObject/asort_disabled.phpt new file mode 100644 index 0000000000000..8f2241332f72e --- /dev/null +++ b/ext/spl/tests/ArrayObject/asort_disabled.phpt @@ -0,0 +1,18 @@ +--TEST-- +ArrayObject when function asort() is disabled +--INI-- +disable_functions=asort +--FILE-- +asort(); +var_dump($ao); + +?> +--EXPECTF-- +Fatal error: Uncaught Error: Cannot call method asort when function asort is disabled in %s:%d +Stack trace: +#0 %s(%d): ArrayObject->asort() +#1 {main} + thrown in %s on line %d diff --git a/ext/spl/tests/ArrayObject/ksort_disabled.phpt b/ext/spl/tests/ArrayObject/ksort_disabled.phpt new file mode 100644 index 0000000000000..258057ad64d31 --- /dev/null +++ b/ext/spl/tests/ArrayObject/ksort_disabled.phpt @@ -0,0 +1,18 @@ +--TEST-- +ArrayObject when function ksort() is disabled +--INI-- +disable_functions=ksort +--FILE-- +ksort(); +var_dump($ao); + +?> +--EXPECTF-- +Fatal error: Uncaught Error: Cannot call method ksort when function ksort is disabled in %s:%d +Stack trace: +#0 %s(%d): ArrayObject->ksort() +#1 {main} + thrown in %s on line %d diff --git a/ext/spl/tests/ArrayObject/natcasesort_disabled.phpt b/ext/spl/tests/ArrayObject/natcasesort_disabled.phpt new file mode 100644 index 0000000000000..336e1245dabc5 --- /dev/null +++ b/ext/spl/tests/ArrayObject/natcasesort_disabled.phpt @@ -0,0 +1,18 @@ +--TEST-- +ArrayObject when function natcasesort() is disabled +--INI-- +disable_functions=natcasesort +--FILE-- +natcasesort(); +var_dump($ao); + +?> +--EXPECTF-- +Fatal error: Uncaught Error: Cannot call method natcasesort when function natcasesort is disabled in %s:%d +Stack trace: +#0 %s(%d): ArrayObject->natcasesort() +#1 {main} + thrown in %s on line %d diff --git a/ext/spl/tests/ArrayObject/natsort_disabled.phpt b/ext/spl/tests/ArrayObject/natsort_disabled.phpt new file mode 100644 index 0000000000000..b674235627adb --- /dev/null +++ b/ext/spl/tests/ArrayObject/natsort_disabled.phpt @@ -0,0 +1,18 @@ +--TEST-- +ArrayObject when function natsort() is disabled +--INI-- +disable_functions=natsort +--FILE-- +natsort(); +var_dump($ao); + +?> +--EXPECTF-- +Fatal error: Uncaught Error: Cannot call method natsort when function natsort is disabled in %s:%d +Stack trace: +#0 %s(%d): ArrayObject->natsort() +#1 {main} + thrown in %s on line %d diff --git a/ext/spl/tests/ArrayObject/uasort_disabled.phpt b/ext/spl/tests/ArrayObject/uasort_disabled.phpt new file mode 100644 index 0000000000000..5a5e9aa57b21a --- /dev/null +++ b/ext/spl/tests/ArrayObject/uasort_disabled.phpt @@ -0,0 +1,18 @@ +--TEST-- +ArrayObject when function uasort() is disabled +--INI-- +disable_functions=uasort +--FILE-- +uasort(fn ($l, $r) => $l <=> $r); +var_dump($ao); + +?> +--EXPECTF-- +Fatal error: Uncaught Error: Cannot call method uasort when function uasort is disabled in %s:%d +Stack trace: +#0 %s(%d): ArrayObject->uasort(Object(Closure)) +#1 {main} + thrown in %s on line %d diff --git a/ext/spl/tests/ArrayObject/uksort_disabled.phpt b/ext/spl/tests/ArrayObject/uksort_disabled.phpt new file mode 100644 index 0000000000000..af703883a3f55 --- /dev/null +++ b/ext/spl/tests/ArrayObject/uksort_disabled.phpt @@ -0,0 +1,18 @@ +--TEST-- +ArrayObject when function uksort() is disabled +--INI-- +disable_functions=uksort +--FILE-- +uksort(fn ($l, $r) => $l <=> $r); +var_dump($ao); + +?> +--EXPECTF-- +Fatal error: Uncaught Error: Cannot call method uksort when function uksort is disabled in %s:%d +Stack trace: +#0 %s(%d): ArrayObject->uksort(Object(Closure)) +#1 {main} + thrown in %s on line %d diff --git a/ext/sqlite3/sqlite3.c b/ext/sqlite3/sqlite3.c index 5e402300980bb..21b6840a8d1b2 100644 --- a/ext/sqlite3/sqlite3.c +++ b/ext/sqlite3/sqlite3.c @@ -1987,6 +1987,16 @@ PHP_METHOD(SQLite3Result, columnType) } /* }}} */ +static void sqlite3result_fill_column_names_cache(php_sqlite3_result *result_obj, int nb_cols) +{ + result_obj->column_names = safe_emalloc(nb_cols, sizeof(zend_string*), 0); + + for (int i = 0; i < nb_cols; i++) { + const char *column = sqlite3_column_name(result_obj->stmt_obj->stmt, i); + result_obj->column_names[i] = zend_string_init(column, strlen(column), 0); + } +} + /* {{{ Fetch a result row as both an associative or numerically indexed array or both. */ PHP_METHOD(SQLite3Result, fetchArray) { @@ -2019,12 +2029,7 @@ PHP_METHOD(SQLite3Result, fetchArray) /* Cache column names to speed up repeated fetchArray calls. */ if (mode & PHP_SQLITE3_ASSOC && !result_obj->column_names) { - result_obj->column_names = emalloc(n_cols * sizeof(zend_string*)); - - for (int i = 0; i < n_cols; i++) { - const char *column = sqlite3_column_name(result_obj->stmt_obj->stmt, i); - result_obj->column_names[i] = zend_string_init(column, strlen(column), 0); - } + sqlite3result_fill_column_names_cache(result_obj, n_cols); } array_init(return_value); @@ -2056,7 +2061,7 @@ static void sqlite3result_clear_column_names_cache(php_sqlite3_result *result) { PHP_METHOD(SQLite3Result, fetchAll) { - int i, nb_cols; + int nb_cols; bool done = false; php_sqlite3_result *result_obj; zval *object = ZEND_THIS; @@ -2071,14 +2076,8 @@ PHP_METHOD(SQLite3Result, fetchAll) SQLITE3_CHECK_INITIALIZED(result_obj->db_obj, result_obj->stmt_obj->initialised, SQLite3Result) nb_cols = sqlite3_column_count(result_obj->stmt_obj->stmt); - if (mode & PHP_SQLITE3_ASSOC) { - sqlite3result_clear_column_names_cache(result_obj); - result_obj->column_names = emalloc(nb_cols * sizeof(zend_string*)); - - for (i = 0; i < nb_cols; i++) { - const char *column = sqlite3_column_name(result_obj->stmt_obj->stmt, i); - result_obj->column_names[i] = zend_string_init(column, strlen(column), 0); - } + if (mode & PHP_SQLITE3_ASSOC && !result_obj->column_names) { + sqlite3result_fill_column_names_cache(result_obj, nb_cols); } result_obj->column_count = nb_cols; array_init(return_value); @@ -2479,9 +2478,7 @@ static zend_always_inline void php_sqlite3_fetch_one(int n_cols, php_sqlite3_res if (mode & PHP_SQLITE3_ASSOC) { if (mode & PHP_SQLITE3_NUM) { - if (Z_REFCOUNTED(data)) { - Z_ADDREF(data); - } + Z_TRY_ADDREF(data); } /* Note: we can't use the "add_new" variant here instead of "update" because * when the same column name is encountered, the last result should be taken. */ diff --git a/ext/sqlite3/tests/sqlite3_explain.phpt b/ext/sqlite3/tests/sqlite3_explain.phpt index f580783ca1d14..40648588733c6 100644 --- a/ext/sqlite3/tests/sqlite3_explain.phpt +++ b/ext/sqlite3/tests/sqlite3_explain.phpt @@ -79,7 +79,7 @@ array(%d) { ["addr"]=> int(1) ["opcode"]=> - string(13) "InitCoroutine" + string(%d) "%s" ["p1"]=> int(3) ["p2"]=> @@ -87,7 +87,7 @@ array(%d) { ["p3"]=> int(2) ["p4"]=> - NULL + %s ["p5"]=> int(0) ["comment"]=> @@ -368,7 +368,7 @@ array(1) { ["parent"]=> int(0) ["notused"]=> - int(0) + int(%d) ["detail"]=> string(17) "SCAN test_explain" } diff --git a/ext/standard/basic_functions.stub.php b/ext/standard/basic_functions.stub.php index 09f63860f1163..740d3014f26a7 100644 --- a/ext/standard/basic_functions.stub.php +++ b/ext/standard/basic_functions.stub.php @@ -124,33 +124,33 @@ /** * @var int - * @deprecated * @cvalue PHP_ASSERT_ACTIVE */ +#[\Deprecated(since: '8.3', message: 'as assert_options() is deprecated')] const ASSERT_ACTIVE = UNKNOWN; /** * @var int - * @deprecated * @cvalue PHP_ASSERT_CALLBACK */ +#[\Deprecated(since: '8.3', message: 'as assert_options() is deprecated')] const ASSERT_CALLBACK = UNKNOWN; /** * @var int - * @deprecated * @cvalue PHP_ASSERT_BAIL */ +#[\Deprecated(since: '8.3', message: 'as assert_options() is deprecated')] const ASSERT_BAIL = UNKNOWN; /** * @var int - * @deprecated * @cvalue PHP_ASSERT_WARNING */ +#[\Deprecated(since: '8.3', message: 'as assert_options() is deprecated')] const ASSERT_WARNING = UNKNOWN; /** * @var int - * @deprecated * @cvalue PHP_ASSERT_EXCEPTION */ +#[\Deprecated(since: '8.3', message: 'as assert_options() is deprecated')] const ASSERT_EXCEPTION = UNKNOWN; /* basic_functions.h */ @@ -1686,13 +1686,11 @@ function array_merge_recursive(array ...$arrays): array {} /** * @compile-time-eval - * @refcount 1 */ function array_replace(array $array, array ...$replacements): array {} /** * @compile-time-eval - * @refcount 1 */ function array_replace_recursive(array $array, array ...$replacements): array {} @@ -1775,19 +1773,16 @@ function array_intersect_key(array $array, array ...$arrays): array {} /** * @param array|callable $rest - * @refcount 1 */ function array_intersect_ukey(array $array, ...$rest): array {} /** * @compile-time-eval - * @refcount 1 */ function array_intersect(array $array, array ...$arrays): array {} /** * @param array|callable $rest - * @refcount 1 */ function array_uintersect(array $array, ...$rest): array {} @@ -1805,13 +1800,11 @@ function array_uintersect_assoc(array $array, ...$rest): array {} /** * @param array|callable $rest - * @refcount 1 */ function array_intersect_uassoc(array $array, ...$rest): array {} /** * @param array|callable $rest - * @refcount 1 */ function array_uintersect_uassoc(array $array, ...$rest): array {} diff --git a/ext/standard/basic_functions_arginfo.h b/ext/standard/basic_functions_arginfo.h index 37df4de7bdfcd..a3d965ad99667 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: dfd7d2cfd31312f7f6c5074c10cab54e9d1fbccc */ + * Stub hash: f8c3745d39ed21f29f46b47f15b6fd1178e55dbb */ 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) @@ -3940,6 +3940,71 @@ static void register_basic_functions_symbols(int module_number) 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); + zend_constant *const_ASSERT_ACTIVE = zend_hash_str_find_ptr(EG(zend_constants), "ASSERT_ACTIVE", sizeof("ASSERT_ACTIVE") - 1); + + zend_attribute *attribute_Deprecated_const_ASSERT_ACTIVE_0 = zend_add_global_constant_attribute(const_ASSERT_ACTIVE, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + zval attribute_Deprecated_const_ASSERT_ACTIVE_0_arg0; + zend_string *attribute_Deprecated_const_ASSERT_ACTIVE_0_arg0_str = zend_string_init("8.3", strlen("8.3"), 1); + ZVAL_STR(&attribute_Deprecated_const_ASSERT_ACTIVE_0_arg0, attribute_Deprecated_const_ASSERT_ACTIVE_0_arg0_str); + ZVAL_COPY_VALUE(&attribute_Deprecated_const_ASSERT_ACTIVE_0->args[0].value, &attribute_Deprecated_const_ASSERT_ACTIVE_0_arg0); + 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); + attribute_Deprecated_const_ASSERT_ACTIVE_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + zend_constant *const_ASSERT_CALLBACK = zend_hash_str_find_ptr(EG(zend_constants), "ASSERT_CALLBACK", sizeof("ASSERT_CALLBACK") - 1); + + zend_attribute *attribute_Deprecated_const_ASSERT_CALLBACK_0 = zend_add_global_constant_attribute(const_ASSERT_CALLBACK, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + zval attribute_Deprecated_const_ASSERT_CALLBACK_0_arg0; + zend_string *attribute_Deprecated_const_ASSERT_CALLBACK_0_arg0_str = zend_string_init("8.3", strlen("8.3"), 1); + ZVAL_STR(&attribute_Deprecated_const_ASSERT_CALLBACK_0_arg0, attribute_Deprecated_const_ASSERT_CALLBACK_0_arg0_str); + ZVAL_COPY_VALUE(&attribute_Deprecated_const_ASSERT_CALLBACK_0->args[0].value, &attribute_Deprecated_const_ASSERT_CALLBACK_0_arg0); + 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); + attribute_Deprecated_const_ASSERT_CALLBACK_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + zend_constant *const_ASSERT_BAIL = zend_hash_str_find_ptr(EG(zend_constants), "ASSERT_BAIL", sizeof("ASSERT_BAIL") - 1); + + zend_attribute *attribute_Deprecated_const_ASSERT_BAIL_0 = zend_add_global_constant_attribute(const_ASSERT_BAIL, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + zval attribute_Deprecated_const_ASSERT_BAIL_0_arg0; + zend_string *attribute_Deprecated_const_ASSERT_BAIL_0_arg0_str = zend_string_init("8.3", strlen("8.3"), 1); + ZVAL_STR(&attribute_Deprecated_const_ASSERT_BAIL_0_arg0, attribute_Deprecated_const_ASSERT_BAIL_0_arg0_str); + ZVAL_COPY_VALUE(&attribute_Deprecated_const_ASSERT_BAIL_0->args[0].value, &attribute_Deprecated_const_ASSERT_BAIL_0_arg0); + 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); + attribute_Deprecated_const_ASSERT_BAIL_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + zend_constant *const_ASSERT_WARNING = zend_hash_str_find_ptr(EG(zend_constants), "ASSERT_WARNING", sizeof("ASSERT_WARNING") - 1); + + zend_attribute *attribute_Deprecated_const_ASSERT_WARNING_0 = zend_add_global_constant_attribute(const_ASSERT_WARNING, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + zval attribute_Deprecated_const_ASSERT_WARNING_0_arg0; + zend_string *attribute_Deprecated_const_ASSERT_WARNING_0_arg0_str = zend_string_init("8.3", strlen("8.3"), 1); + ZVAL_STR(&attribute_Deprecated_const_ASSERT_WARNING_0_arg0, attribute_Deprecated_const_ASSERT_WARNING_0_arg0_str); + ZVAL_COPY_VALUE(&attribute_Deprecated_const_ASSERT_WARNING_0->args[0].value, &attribute_Deprecated_const_ASSERT_WARNING_0_arg0); + 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); + attribute_Deprecated_const_ASSERT_WARNING_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + zend_constant *const_ASSERT_EXCEPTION = zend_hash_str_find_ptr(EG(zend_constants), "ASSERT_EXCEPTION", sizeof("ASSERT_EXCEPTION") - 1); + + zend_attribute *attribute_Deprecated_const_ASSERT_EXCEPTION_0 = zend_add_global_constant_attribute(const_ASSERT_EXCEPTION, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + zval attribute_Deprecated_const_ASSERT_EXCEPTION_0_arg0; + zend_string *attribute_Deprecated_const_ASSERT_EXCEPTION_0_arg0_str = zend_string_init("8.3", strlen("8.3"), 1); + ZVAL_STR(&attribute_Deprecated_const_ASSERT_EXCEPTION_0_arg0, attribute_Deprecated_const_ASSERT_EXCEPTION_0_arg0_str); + ZVAL_COPY_VALUE(&attribute_Deprecated_const_ASSERT_EXCEPTION_0->args[0].value, &attribute_Deprecated_const_ASSERT_EXCEPTION_0_arg0); + 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); + attribute_Deprecated_const_ASSERT_EXCEPTION_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); } static zend_class_entry *register_class___PHP_Incomplete_Class(void) diff --git a/ext/standard/file.c b/ext/standard/file.c index 4e136bedf5fab..ab6ed4fbadd2d 100644 --- a/ext/standard/file.c +++ b/ext/standard/file.c @@ -98,6 +98,7 @@ php_file_globals file_globals; # include #endif +#include "zend_attributes.h" #include "file_arginfo.h" /* }}} */ diff --git a/ext/standard/file.stub.php b/ext/standard/file.stub.php index 591169a37e001..91d2ea08708ec 100644 --- a/ext/standard/file.stub.php +++ b/ext/standard/file.stub.php @@ -446,13 +446,13 @@ /** * @var int - * @deprecated */ +#[\Deprecated(since: '8.1', message: 'as the constant has no effect')] const FILE_TEXT = 0; /** * @var int - * @deprecated */ +#[\Deprecated(since: '8.1', message: 'as the constant has no effect')] const FILE_BINARY = 0; #ifdef HAVE_FNMATCH diff --git a/ext/standard/file_arginfo.h b/ext/standard/file_arginfo.h index 7dc8fcf80aabe..276419b9abaa7 100644 --- a/ext/standard/file_arginfo.h +++ b/ext/standard/file_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: e9a566d5ef96f781074027b1b3ff1824d0208b47 */ + * Stub hash: dde0b40909dbadb565d898338834de7fa689c5e9 */ static void register_file_symbols(int module_number) { @@ -118,4 +118,31 @@ static void register_file_symbols(int module_number) #if defined(HAVE_FNMATCH) && defined(FNM_CASEFOLD) REGISTER_LONG_CONSTANT("FNM_CASEFOLD", FNM_CASEFOLD, CONST_PERSISTENT); #endif + + zend_constant *const_FILE_TEXT = zend_hash_str_find_ptr(EG(zend_constants), "FILE_TEXT", sizeof("FILE_TEXT") - 1); + + zend_attribute *attribute_Deprecated_const_FILE_TEXT_0 = zend_add_global_constant_attribute(const_FILE_TEXT, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + zval attribute_Deprecated_const_FILE_TEXT_0_arg0; + zend_string *attribute_Deprecated_const_FILE_TEXT_0_arg0_str = zend_string_init("8.1", strlen("8.1"), 1); + ZVAL_STR(&attribute_Deprecated_const_FILE_TEXT_0_arg0, attribute_Deprecated_const_FILE_TEXT_0_arg0_str); + ZVAL_COPY_VALUE(&attribute_Deprecated_const_FILE_TEXT_0->args[0].value, &attribute_Deprecated_const_FILE_TEXT_0_arg0); + 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); + attribute_Deprecated_const_FILE_TEXT_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + zend_constant *const_FILE_BINARY = zend_hash_str_find_ptr(EG(zend_constants), "FILE_BINARY", sizeof("FILE_BINARY") - 1); + + zend_attribute *attribute_Deprecated_const_FILE_BINARY_0 = zend_add_global_constant_attribute(const_FILE_BINARY, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + zval attribute_Deprecated_const_FILE_BINARY_0_arg0; + zend_string *attribute_Deprecated_const_FILE_BINARY_0_arg0_str = zend_string_init("8.1", strlen("8.1"), 1); + ZVAL_STR(&attribute_Deprecated_const_FILE_BINARY_0_arg0, attribute_Deprecated_const_FILE_BINARY_0_arg0_str); + ZVAL_COPY_VALUE(&attribute_Deprecated_const_FILE_BINARY_0->args[0].value, &attribute_Deprecated_const_FILE_BINARY_0_arg0); + 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); + attribute_Deprecated_const_FILE_BINARY_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); } diff --git a/ext/standard/fsock.c b/ext/standard/fsock.c index cb7a471e935a6..2b9e00a57554c 100644 --- a/ext/standard/fsock.c +++ b/ext/standard/fsock.c @@ -23,6 +23,28 @@ #include "php_network.h" #include "file.h" +static size_t php_fsockopen_format_host_port(char **message, const char *prefix, size_t prefix_len, + const char *host, size_t host_len, zend_long port) +{ + char portbuf[32]; + int portlen = snprintf(portbuf, sizeof(portbuf), ":" ZEND_LONG_FMT, port); + size_t total_len = prefix_len + host_len + portlen; + + char *result = emalloc(total_len + 1); + + if (prefix_len > 0) { + memcpy(result, prefix, prefix_len); + } + memcpy(result + prefix_len, host, host_len); + memcpy(result + prefix_len + host_len, portbuf, portlen); + + result[total_len] = '\0'; + + *message = result; + + return total_len; +} + /* {{{ php_fsockopen() */ static void php_fsockopen_stream(INTERNAL_FUNCTION_PARAMETERS, int persistent) @@ -62,11 +84,12 @@ static void php_fsockopen_stream(INTERNAL_FUNCTION_PARAMETERS, int persistent) } if (persistent) { - spprintf(&hashkey, 0, "pfsockopen__%s:" ZEND_LONG_FMT, host, port); + php_fsockopen_format_host_port(&hashkey, "pfsockopen__", strlen("pfsockopen__"), host, + host_len, port); } if (port > 0) { - hostname_len = spprintf(&hostname, 0, "%s:" ZEND_LONG_FMT, host, port); + hostname_len = php_fsockopen_format_host_port(&hostname, "", 0, host, host_len, port); } else { hostname_len = host_len; hostname = host; diff --git a/ext/standard/pack.c b/ext/standard/pack.c index d4c5cc1f04cfa..bcac949d56329 100644 --- a/ext/standard/pack.c +++ b/ext/standard/pack.c @@ -366,7 +366,7 @@ PHP_FUNCTION(pack) switch (code) { case 'h': case 'H': - INC_OUTPUTPOS((arg + (arg % 2)) / 2,1) /* 4 bit per arg */ + INC_OUTPUTPOS((arg / 2) + (arg % 2),1) /* 4 bit per arg */ break; case 'a': diff --git a/ext/standard/string.c b/ext/standard/string.c index 36903b3c5c7b9..75be1f1dcab1c 100644 --- a/ext/standard/string.c +++ b/ext/standard/string.c @@ -2404,7 +2404,7 @@ PHP_FUNCTION(substr_replace) if (repl_idx < repl_ht->nNumUsed) { repl_str = zval_get_tmp_string(tmp_repl, &tmp_repl_str); } else { - repl_str = STR_EMPTY_ALLOC(); + repl_str = ZSTR_EMPTY_ALLOC(); } } diff --git a/ext/standard/tests/array/rcn_in_place.phpt b/ext/standard/tests/array/rcn_in_place.phpt new file mode 100644 index 0000000000000..e6a7b5b6d695f --- /dev/null +++ b/ext/standard/tests/array/rcn_in_place.phpt @@ -0,0 +1,57 @@ +--TEST-- +RCN check for in-place array modifications +--FILE-- + 0)); +var_dump(array_intersect(range(0, 1), [])); +var_dump(array_uintersect(range(0, 1), [], fn () => 0)); +var_dump(array_intersect_uassoc(range(0, 1), [], fn () => 0)); +var_dump(array_uintersect_uassoc(range(0, 1), [], fn () => 0, fn () => 0)); +?> +--EXPECT-- +array(2) { + [0]=> + int(0) + [1]=> + int(1) +} +array(2) { + [0]=> + int(0) + [1]=> + int(1) +} +array(2) { + [0]=> + int(0) + [1]=> + int(1) +} +array(2) { + [0]=> + int(0) + [1]=> + int(1) +} +array(2) { + [0]=> + int(0) + [1]=> + int(1) +} +array(0) { +} +array(0) { +} +array(0) { +} +array(0) { +} +array(0) { +} diff --git a/ext/standard/tests/assert/assert.phpt b/ext/standard/tests/assert/assert.phpt index 4649e9a59be94..a275b9949cbe6 100644 --- a/ext/standard/tests/assert/assert.phpt +++ b/ext/standard/tests/assert/assert.phpt @@ -41,25 +41,25 @@ Deprecated: PHP Startup: assert.active INI setting is deprecated in Unknown on l Deprecated: PHP Startup: assert.exception INI setting is deprecated in Unknown on line 0 -Deprecated: Constant ASSERT_ACTIVE is deprecated in %s on line %d +Deprecated: Constant ASSERT_ACTIVE is deprecated since 8.3, as assert_options() is deprecated in %s on line %d Deprecated: Function assert_options() is deprecated since 8.3 in %s on line %d -Deprecated: Constant ASSERT_WARNING is deprecated in %s on line %d +Deprecated: Constant ASSERT_WARNING is deprecated since 8.3, as assert_options() is deprecated in %s on line %d Deprecated: Function assert_options() is deprecated since 8.3 in %s on line %d -Deprecated: Constant ASSERT_CALLBACK is deprecated in %s on line %d +Deprecated: Constant ASSERT_CALLBACK is deprecated since 8.3, as assert_options() is deprecated in %s on line %d Deprecated: Function assert_options() is deprecated since 8.3 in %s on line %d assertion failed 21,"assert($a != 0)" -Deprecated: Constant ASSERT_CALLBACK is deprecated in %s on line %d +Deprecated: Constant ASSERT_CALLBACK is deprecated since 8.3, as assert_options() is deprecated in %s on line %d Deprecated: Function assert_options() is deprecated since 8.3 in %s on line %d class assertion failed 24,"assert($a != 0)" -Deprecated: Constant ASSERT_CALLBACK is deprecated in %s on line %d +Deprecated: Constant ASSERT_CALLBACK is deprecated since 8.3, as assert_options() is deprecated in %s on line %d Deprecated: Function assert_options() is deprecated since 8.3 in %s on line %d class assertion failed 28,"assert($a != 0)" diff --git a/ext/standard/tests/assert/assert03.phpt b/ext/standard/tests/assert/assert03.phpt index 2a62665893a88..968af83065036 100644 --- a/ext/standard/tests/assert/assert03.phpt +++ b/ext/standard/tests/assert/assert03.phpt @@ -36,15 +36,15 @@ Deprecated: PHP Startup: assert.warning INI setting is deprecated in Unknown on Deprecated: PHP Startup: assert.exception INI setting is deprecated in Unknown on line 0 -Deprecated: Constant ASSERT_ACTIVE is deprecated in %s on line %d +Deprecated: Constant ASSERT_ACTIVE is deprecated since 8.3, as assert_options() is deprecated in %s on line %d Deprecated: Function assert_options() is deprecated since 8.3 in %s on line %d -Deprecated: Constant ASSERT_WARNING is deprecated in %s on line %d +Deprecated: Constant ASSERT_WARNING is deprecated since 8.3, as assert_options() is deprecated in %s on line %d Deprecated: Function assert_options() is deprecated since 8.3 in %s on line %d -Deprecated: Constant ASSERT_CALLBACK is deprecated in %s on line %d +Deprecated: Constant ASSERT_CALLBACK is deprecated since 8.3, as assert_options() is deprecated in %s on line %d Deprecated: Function assert_options() is deprecated since 8.3 in %s on line %d assertion failed - a - 18,"assert($a != 0)" diff --git a/ext/standard/tests/assert/assert04.phpt b/ext/standard/tests/assert/assert04.phpt index 9935d4c6a123c..744633c197be2 100644 --- a/ext/standard/tests/assert/assert04.phpt +++ b/ext/standard/tests/assert/assert04.phpt @@ -29,17 +29,17 @@ echo "not reached\n"; --EXPECTF-- Deprecated: PHP Startup: assert.exception INI setting is deprecated in Unknown on line 0 -Deprecated: Constant ASSERT_ACTIVE is deprecated in %s on line %d +Deprecated: Constant ASSERT_ACTIVE is deprecated since 8.3, as assert_options() is deprecated in %s on line %d Deprecated: Function assert_options() is deprecated since 8.3 in %s on line %d -Deprecated: Constant ASSERT_ACTIVE is deprecated in %s on line %d +Deprecated: Constant ASSERT_ACTIVE is deprecated since 8.3, as assert_options() is deprecated in %s on line %d Deprecated: Function assert_options() is deprecated since 8.3 in %s on line %d Warning: assert(): assert(0) failed in %s on line %d -Deprecated: Constant ASSERT_BAIL is deprecated in %s on line %d +Deprecated: Constant ASSERT_BAIL is deprecated since 8.3, as assert_options() is deprecated in %s on line %d Deprecated: Function assert_options() is deprecated since 8.3 in %s on line %d diff --git a/ext/standard/tests/assert/assert_basic2.phpt b/ext/standard/tests/assert/assert_basic2.phpt index fdd1c53b93dde..6bca82a91f536 100644 --- a/ext/standard/tests/assert/assert_basic2.phpt +++ b/ext/standard/tests/assert/assert_basic2.phpt @@ -30,7 +30,7 @@ Deprecated: PHP Startup: assert.callback INI setting is deprecated in Unknown on Deprecated: PHP Startup: assert.exception INI setting is deprecated in Unknown on line 0 -Deprecated: Constant ASSERT_CALLBACK is deprecated in %s on line %d +Deprecated: Constant ASSERT_CALLBACK is deprecated since 8.3, as assert_options() is deprecated in %s on line %d Deprecated: Function assert_options() is deprecated since 8.3 in %s on line %d string(2) "f1" @@ -38,12 +38,12 @@ f1 called Warning: assert(): assert(0) failed in %s on line %d -Deprecated: Constant ASSERT_CALLBACK is deprecated in %s on line %d +Deprecated: Constant ASSERT_CALLBACK is deprecated since 8.3, as assert_options() is deprecated in %s on line %d Deprecated: Function assert_options() is deprecated since 8.3 in %s on line %d string(2) "f1" -Deprecated: Constant ASSERT_CALLBACK is deprecated in %s on line %d +Deprecated: Constant ASSERT_CALLBACK is deprecated since 8.3, as assert_options() is deprecated in %s on line %d Deprecated: Function assert_options() is deprecated since 8.3 in %s on line %d string(2) "f2" diff --git a/ext/standard/tests/assert/assert_basic3.phpt b/ext/standard/tests/assert/assert_basic3.phpt index 0849f16e6f208..4e281ef504245 100644 --- a/ext/standard/tests/assert/assert_basic3.phpt +++ b/ext/standard/tests/assert/assert_basic3.phpt @@ -23,7 +23,7 @@ Deprecated: PHP Startup: assert.callback INI setting is deprecated in Unknown on Deprecated: PHP Startup: assert.exception INI setting is deprecated in Unknown on line 0 -Deprecated: Constant ASSERT_BAIL is deprecated in %s on line %d +Deprecated: Constant ASSERT_BAIL is deprecated since 8.3, as assert_options() is deprecated in %s on line %d Deprecated: Function assert_options() is deprecated since 8.3 in %s on line %d int(0) diff --git a/ext/standard/tests/assert/assert_basic4.phpt b/ext/standard/tests/assert/assert_basic4.phpt index 76ade8d00f403..cc9ec64328866 100644 --- a/ext/standard/tests/assert/assert_basic4.phpt +++ b/ext/standard/tests/assert/assert_basic4.phpt @@ -28,22 +28,22 @@ Deprecated: PHP Startup: assert.warning INI setting is deprecated in Unknown on Deprecated: PHP Startup: assert.callback INI setting is deprecated in Unknown on line 0 -Deprecated: Constant ASSERT_ACTIVE is deprecated in %s on line %d +Deprecated: Constant ASSERT_ACTIVE is deprecated since 8.3, as assert_options() is deprecated in %s on line %d Deprecated: Function assert_options() is deprecated since 8.3 in %s on line %d Initial values: assert_options(ASSERT_ACTIVE) => [0] -Deprecated: Constant ASSERT_WARNING is deprecated in %s on line %d +Deprecated: Constant ASSERT_WARNING is deprecated since 8.3, as assert_options() is deprecated in %s on line %d Deprecated: Function assert_options() is deprecated since 8.3 in %s on line %d Initial values: assert_options(ASSERT_WARNING) => [0] -Deprecated: Constant ASSERT_BAIL is deprecated in %s on line %d +Deprecated: Constant ASSERT_BAIL is deprecated since 8.3, as assert_options() is deprecated in %s on line %d Deprecated: Function assert_options() is deprecated since 8.3 in %s on line %d Initial values: assert_options(ASSERT_BAIL) => [0] -Deprecated: Constant ASSERT_CALLBACK is deprecated in %s on line %d +Deprecated: Constant ASSERT_CALLBACK is deprecated since 8.3, as assert_options() is deprecated in %s on line %d Deprecated: Function assert_options() is deprecated since 8.3 in %s on line %d Initial values: assert_options(ASSERT_CALLBACK) => [f1] diff --git a/ext/standard/tests/assert/assert_basic5.phpt b/ext/standard/tests/assert/assert_basic5.phpt index 6ba70d94cdf36..66858eed5cb81 100644 --- a/ext/standard/tests/assert/assert_basic5.phpt +++ b/ext/standard/tests/assert/assert_basic5.phpt @@ -28,7 +28,7 @@ Deprecated: PHP Startup: assert.callback INI setting is deprecated in Unknown on Deprecated: PHP Startup: assert.exception INI setting is deprecated in Unknown on line 0 -Deprecated: Constant ASSERT_WARNING is deprecated in %s on line %d +Deprecated: Constant ASSERT_WARNING is deprecated since 8.3, as assert_options() is deprecated in %s on line %d Deprecated: Function assert_options() is deprecated since 8.3 in %s on line %d int(0) @@ -38,7 +38,7 @@ Warning: assert(): assert(0 != 0) failed in %s on line %d bool(false) bool(true) -Deprecated: Constant ASSERT_WARNING is deprecated in %s on line %d +Deprecated: Constant ASSERT_WARNING is deprecated since 8.3, as assert_options() is deprecated in %s on line %d Deprecated: Function assert_options() is deprecated since 8.3 in %s on line %d int(1) diff --git a/ext/standard/tests/assert/assert_basic6.phpt b/ext/standard/tests/assert/assert_basic6.phpt index 4e95fdb01dc4c..b531425912c21 100644 --- a/ext/standard/tests/assert/assert_basic6.phpt +++ b/ext/standard/tests/assert/assert_basic6.phpt @@ -32,11 +32,11 @@ try { ?> --EXPECTF-- -Deprecated: Constant ASSERT_CALLBACK is deprecated in %s on line %d +Deprecated: Constant ASSERT_CALLBACK is deprecated since 8.3, as assert_options() is deprecated in %s on line %d Deprecated: Function assert_options() is deprecated since 8.3 in %s on line %d -Deprecated: Constant ASSERT_CALLBACK is deprecated in %s on line %d +Deprecated: Constant ASSERT_CALLBACK is deprecated since 8.3, as assert_options() is deprecated in %s on line %d Deprecated: Function assert_options() is deprecated since 8.3 in %s on line %d string(2) "f1" @@ -44,11 +44,11 @@ foo assert(false) -Deprecated: Constant ASSERT_CALLBACK is deprecated in %s on line %d +Deprecated: Constant ASSERT_CALLBACK is deprecated since 8.3, as assert_options() is deprecated in %s on line %d Deprecated: Function assert_options() is deprecated since 8.3 in %s on line %d -Deprecated: Constant ASSERT_CALLBACK is deprecated in %s on line %d +Deprecated: Constant ASSERT_CALLBACK is deprecated since 8.3, as assert_options() is deprecated in %s on line %d Deprecated: Function assert_options() is deprecated since 8.3 in %s on line %d NULL diff --git a/ext/standard/tests/assert/assert_closures.phpt b/ext/standard/tests/assert/assert_closures.phpt index aa7246ee21bee..ecce049860236 100644 --- a/ext/standard/tests/assert/assert_closures.phpt +++ b/ext/standard/tests/assert/assert_closures.phpt @@ -13,7 +13,7 @@ assert(0); --EXPECTF-- Deprecated: PHP Startup: assert.exception INI setting is deprecated in Unknown on line 0 -Deprecated: Constant ASSERT_CALLBACK is deprecated in %s on line %d +Deprecated: Constant ASSERT_CALLBACK is deprecated since 8.3, as assert_options() is deprecated in %s on line %d Deprecated: Function assert_options() is deprecated since 8.3 in %s on line %d Hello World! diff --git a/ext/standard/tests/assert/assert_closures_multiple.phpt b/ext/standard/tests/assert/assert_closures_multiple.phpt index 0786740155571..8f0cb9551ab93 100644 --- a/ext/standard/tests/assert/assert_closures_multiple.phpt +++ b/ext/standard/tests/assert/assert_closures_multiple.phpt @@ -32,7 +32,7 @@ try { ?> DONE --EXPECTF-- -Deprecated: Constant ASSERT_CALLBACK is deprecated in %s on line %d +Deprecated: Constant ASSERT_CALLBACK is deprecated since 8.3, as assert_options() is deprecated in %s on line %d Deprecated: Function assert_options() is deprecated since 8.3 in %s on line %d DONE diff --git a/ext/standard/tests/assert/assert_error2.phpt b/ext/standard/tests/assert/assert_error2.phpt index eaa62523845d4..6cfa5a6ce4447 100644 --- a/ext/standard/tests/assert/assert_error2.phpt +++ b/ext/standard/tests/assert/assert_error2.phpt @@ -25,7 +25,7 @@ Deprecated: PHP Startup: assert.callback INI setting is deprecated in Unknown on Deprecated: PHP Startup: assert.exception INI setting is deprecated in Unknown on line 0 -Deprecated: Constant ASSERT_BAIL is deprecated in %s on line %d +Deprecated: Constant ASSERT_BAIL is deprecated since 8.3, as assert_options() is deprecated in %s on line %d Deprecated: Function assert_options() is deprecated since 8.3 in %s on line %d int(0) diff --git a/ext/standard/tests/assert/assert_variation.phpt b/ext/standard/tests/assert/assert_variation.phpt index 494f6cd579384..6824f7246d5b6 100644 --- a/ext/standard/tests/assert/assert_variation.phpt +++ b/ext/standard/tests/assert/assert_variation.phpt @@ -85,7 +85,7 @@ Deprecated: PHP Startup: assert.callback INI setting is deprecated in Unknown on Deprecated: PHP Startup: assert.exception INI setting is deprecated in Unknown on line 0 -Deprecated: Constant ASSERT_CALLBACK is deprecated in %s on line %d +Deprecated: Constant ASSERT_CALLBACK is deprecated since 8.3, as assert_options() is deprecated in %s on line %d Deprecated: Function assert_options() is deprecated since 8.3 in %s on line %d Initial values: assert_options(ASSERT_CALLBACK) => [f1] @@ -98,7 +98,7 @@ Change callback function using ini.set and test return value Deprecated: ini_set(): assert.callback INI setting is deprecated in %s on line %d string(2) "f1" -Deprecated: Constant ASSERT_CALLBACK is deprecated in %s on line %d +Deprecated: Constant ASSERT_CALLBACK is deprecated since 8.3, as assert_options() is deprecated in %s on line %d Deprecated: Function assert_options() is deprecated since 8.3 in %s on line %d assert_options(ASSERT_CALLBACK) => [f2] @@ -108,12 +108,12 @@ bool(false) Change callback function using assert_options and test return value -Deprecated: Constant ASSERT_CALLBACK is deprecated in %s on line %d +Deprecated: Constant ASSERT_CALLBACK is deprecated since 8.3, as assert_options() is deprecated in %s on line %d Deprecated: Function assert_options() is deprecated since 8.3 in %s on line %d string(2) "f2" -Deprecated: Constant ASSERT_CALLBACK is deprecated in %s on line %d +Deprecated: Constant ASSERT_CALLBACK is deprecated since 8.3, as assert_options() is deprecated in %s on line %d Deprecated: Function assert_options() is deprecated since 8.3 in %s on line %d assert_options(ASSERT_CALLBACK) => [f3] @@ -123,12 +123,12 @@ bool(false) Reset the name of the callback routine to a class method -Deprecated: Constant ASSERT_CALLBACK is deprecated in %s on line %d +Deprecated: Constant ASSERT_CALLBACK is deprecated since 8.3, as assert_options() is deprecated in %s on line %d Deprecated: Function assert_options() is deprecated since 8.3 in %s on line %d string(2) "f3" -Deprecated: Constant ASSERT_CALLBACK is deprecated in %s on line %d +Deprecated: Constant ASSERT_CALLBACK is deprecated since 8.3, as assert_options() is deprecated in %s on line %d Deprecated: Function assert_options() is deprecated since 8.3 in %s on line %d assert_options(ASSERT_CALLBACK) => [c1] @@ -137,12 +137,12 @@ Invalid callback c1, function "c1" not found or invalid function name Reset callback options to use a class method -Deprecated: Constant ASSERT_CALLBACK is deprecated in %s on line %d +Deprecated: Constant ASSERT_CALLBACK is deprecated since 8.3, as assert_options() is deprecated in %s on line %d Deprecated: Function assert_options() is deprecated since 8.3 in %s on line %d string(2) "c1" -Deprecated: Constant ASSERT_CALLBACK is deprecated in %s on line %d +Deprecated: Constant ASSERT_CALLBACK is deprecated since 8.3, as assert_options() is deprecated in %s on line %d Deprecated: Function assert_options() is deprecated since 8.3 in %s on line %d array(2) { @@ -158,7 +158,7 @@ bool(false) Reset callback options to use an object method -Deprecated: Constant ASSERT_CALLBACK is deprecated in %s on line %d +Deprecated: Constant ASSERT_CALLBACK is deprecated since 8.3, as assert_options() is deprecated in %s on line %d Deprecated: Function assert_options() is deprecated since 8.3 in %s on line %d array(2) { @@ -168,7 +168,7 @@ array(2) { string(6) "assert" } -Deprecated: Constant ASSERT_CALLBACK is deprecated in %s on line %d +Deprecated: Constant ASSERT_CALLBACK is deprecated since 8.3, as assert_options() is deprecated in %s on line %d Deprecated: Function assert_options() is deprecated since 8.3 in %s on line %d array(2) { @@ -185,11 +185,11 @@ bool(false) Set callback to something silly -Deprecated: Constant ASSERT_CALLBACK is deprecated in %s on line %d +Deprecated: Constant ASSERT_CALLBACK is deprecated since 8.3, as assert_options() is deprecated in %s on line %d Deprecated: Function assert_options() is deprecated since 8.3 in %s on line %d -Deprecated: Constant ASSERT_CALLBACK is deprecated in %s on line %d +Deprecated: Constant ASSERT_CALLBACK is deprecated since 8.3, as assert_options() is deprecated in %s on line %d Deprecated: Function assert_options() is deprecated since 8.3 in %s on line %d float(3.141) diff --git a/ext/standard/tests/assert/bug80290.phpt b/ext/standard/tests/assert/bug80290.phpt index 8b737f33043f9..112dbde1a4e47 100644 --- a/ext/standard/tests/assert/bug80290.phpt +++ b/ext/standard/tests/assert/bug80290.phpt @@ -12,7 +12,7 @@ assert(false, 'Dynamic message: ' . $x); ?> --EXPECTF-- -Deprecated: Constant ASSERT_CALLBACK is deprecated in %s on line %d +Deprecated: Constant ASSERT_CALLBACK is deprecated since 8.3, as assert_options() is deprecated in %s on line %d Deprecated: Function assert_options() is deprecated since 8.3 in %s on line %d string(18) "Dynamic message: x" diff --git a/ext/standard/tests/file/file_binary_text_deprecated.phpt b/ext/standard/tests/file/file_binary_text_deprecated.phpt index cbc57809c6175..b6967c5967103 100644 --- a/ext/standard/tests/file/file_binary_text_deprecated.phpt +++ b/ext/standard/tests/file/file_binary_text_deprecated.phpt @@ -8,8 +8,8 @@ var_dump(FILE_TEXT); ?> --EXPECTF-- -Deprecated: Constant FILE_BINARY is deprecated in %s on line %d +Deprecated: Constant FILE_BINARY is deprecated since 8.1, as the constant has no effect in %s on line %d int(0) -Deprecated: Constant FILE_TEXT is deprecated in %s on line %d +Deprecated: Constant FILE_TEXT is deprecated since 8.1, as the constant has no effect in %s on line %d int(0) diff --git a/ext/standard/tests/network/ghsa-3cr5-j632-f35r.phpt b/ext/standard/tests/network/ghsa-3cr5-j632-f35r.phpt new file mode 100644 index 0000000000000..7556c3be94ccd --- /dev/null +++ b/ext/standard/tests/network/ghsa-3cr5-j632-f35r.phpt @@ -0,0 +1,21 @@ +--TEST-- +GHSA-3cr5-j632-f35r: Null byte termination in fsockopen() +--FILE-- + +--EXPECTF-- + +Warning: fsockopen(): Unable to connect to localhost:%d (The hostname must not contain null bytes) in %s +bool(false) diff --git a/ext/standard/tests/streams/ghsa-3cr5-j632-f35r.phpt b/ext/standard/tests/streams/ghsa-3cr5-j632-f35r.phpt new file mode 100644 index 0000000000000..52f9263c99aaa --- /dev/null +++ b/ext/standard/tests/streams/ghsa-3cr5-j632-f35r.phpt @@ -0,0 +1,26 @@ +--TEST-- +GHSA-3cr5-j632-f35r: Null byte termination in stream_socket_client() +--FILE-- + +--EXPECTF-- + +Warning: stream_socket_client(): Unable to connect to tcp://localhost\0.example.com:%d (The hostname must not contain null bytes) in %s +bool(false) diff --git a/ext/standard/tests/strings/gh18976.phpt b/ext/standard/tests/strings/gh18976.phpt new file mode 100644 index 0000000000000..aa58167f9d45b --- /dev/null +++ b/ext/standard/tests/strings/gh18976.phpt @@ -0,0 +1,14 @@ +--TEST-- +GH-18976 (pack overflow with h/H format) +--INI-- +memory_limit=-1 +--FILE-- + +--EXPECTF-- + +Warning: pack(): Type h: not enough characters in string in %s on line %d + +Warning: pack(): Type H: not enough characters in string in %s on line %d diff --git a/ext/uri/config.m4 b/ext/uri/config.m4 index 08dc044d8d29f..2f5a7a489b5ae 100644 --- a/ext/uri/config.m4 +++ b/ext/uri/config.m4 @@ -5,18 +5,19 @@ PHP_INSTALL_HEADERS([ext/uri], m4_normalize([ php_lexbor.h php_uri.h php_uri_common.h + php_uriparser.h ])) AC_DEFINE([URI_ENABLE_ANSI], [1], [Define to 1 for enabling ANSI support of uriparser.]) AC_DEFINE([URI_NO_UNICODE], [1], [Define to 1 for disabling unicode support of uriparser.]) URIPARSER_DIR="uriparser" -URIPARSER_SOURCES="$URIPARSER_DIR/src/UriCommon.c $URIPARSER_DIR/src/UriCompare.c $URIPARSER_DIR/src/UriEscape.c \ -$URIPARSER_DIR/src/UriFile.c $URIPARSER_DIR/src/UriIp4.c $URIPARSER_DIR/src/UriIp4Base.c \ +URIPARSER_SOURCES="$URIPARSER_DIR/src/UriCommon.c $URIPARSER_DIR/src/UriCompare.c $URIPARSER_DIR/src/UriCopy.c \ +$URIPARSER_DIR/src/UriEscape.c $URIPARSER_DIR/src/UriFile.c $URIPARSER_DIR/src/UriIp4.c $URIPARSER_DIR/src/UriIp4Base.c \ $URIPARSER_DIR/src/UriMemory.c $URIPARSER_DIR/src/UriNormalize.c $URIPARSER_DIR/src/UriNormalizeBase.c \ $URIPARSER_DIR/src/UriParse.c $URIPARSER_DIR/src/UriParseBase.c $URIPARSER_DIR/src/UriQuery.c \ $URIPARSER_DIR/src/UriRecompose.c $URIPARSER_DIR/src/UriResolve.c $URIPARSER_DIR/src/UriShorten.c" -PHP_NEW_EXTENSION(uri, [php_lexbor.c php_uri.c php_uri_common.c $URIPARSER_SOURCES], [no],,[-I$ext_srcdir/$URIPARSER_DIR/include -DURI_STATIC_BUILD -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1]) +PHP_NEW_EXTENSION(uri, [php_lexbor.c php_uri.c php_uri_common.c php_uriparser.c $URIPARSER_SOURCES], [no],,[-I$ext_srcdir/$URIPARSER_DIR/include -DURI_STATIC_BUILD -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1]) PHP_ADD_EXTENSION_DEP(uri, lexbor) PHP_ADD_BUILD_DIR($ext_builddir/$URIPARSER_DIR/src $ext_builddir/$URIPARSER_DIR/include) diff --git a/ext/uri/config.w32 b/ext/uri/config.w32 index 9c6af0cc5fa7b..6954ca06af555 100644 --- a/ext/uri/config.w32 +++ b/ext/uri/config.w32 @@ -1,9 +1,9 @@ -EXTENSION("uri", "php_lexbor.c php_uri.c php_uri_common.c", false /* never shared */, "/I ext/lexbor /I ext/uri/uriparser/include /DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); +EXTENSION("uri", "php_lexbor.c php_uri.c php_uri_common.c php_uriparser.c", false /* never shared */, "/I ext/lexbor /I ext/uri/uriparser/include /DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); AC_DEFINE("URI_ENABLE_ANSI", 1, "Define to 1 for enabling ANSI support of uriparser.") AC_DEFINE("URI_NO_UNICODE", 1, "Define to 1 for disabling unicode support of uriparser.") ADD_FLAG("CFLAGS_URI", "/D URI_STATIC_BUILD"); ADD_EXTENSION_DEP('uri', 'lexbor'); -ADD_SOURCES("ext/uri/uriparser/src", "UriCommon.c UriCompare.c UriEscape.c UriFile.c UriIp4.c UriIp4Base.c UriMemory.c UriNormalize.c UriNormalizeBase.c UriParse.c UriParseBase.c UriQuery.c UriRecompose.c UriShorten.c", "uri"); -PHP_INSTALL_HEADERS("ext/uri", "php_lexbor.h php_uri.h php_uri_common.h uriparser/src uriparser/include"); +ADD_SOURCES("ext/uri/uriparser/src", "UriCommon.c UriCompare.c UriCopy.c UriEscape.c UriFile.c UriIp4.c UriIp4Base.c UriMemory.c UriNormalize.c UriNormalizeBase.c UriParse.c UriParseBase.c UriQuery.c UriRecompose.c UriResolve.c UriShorten.c", "uri"); +PHP_INSTALL_HEADERS("ext/uri", "php_lexbor.h php_uri.h php_uri_common.h php_uriparser.h uriparser/src uriparser/include"); diff --git a/ext/uri/php_lexbor.c b/ext/uri/php_lexbor.c index 44bca30f8fda7..39b0fb7d09ce3 100644 --- a/ext/uri/php_lexbor.c +++ b/ext/uri/php_lexbor.c @@ -73,7 +73,7 @@ static void lexbor_cleanup_parser(void) * When errors is NULL, the caller is not interested in the additional error information, * so the function does nothing. */ -static zend_string *fill_errors(zval *errors) +static const char *fill_errors(zval *errors) { if (errors == NULL) { return NULL; @@ -87,140 +87,138 @@ static zend_string *fill_errors(zval *errors) return NULL; } - zend_string *result = NULL; + const char *result = NULL; lexbor_plog_entry_t *lxb_error; while ((lxb_error = lexbor_array_obj_pop(&lexbor_parser.log->list)) != NULL) { zval error; object_init_ex(&error, uri_whatwg_url_validation_error_ce); zend_update_property_string(uri_whatwg_url_validation_error_ce, Z_OBJ(error), ZEND_STRL("context"), (const char *) lxb_error->data); - zend_string *error_str; + const char *error_str; zval failure; switch (lxb_error->id) { case LXB_URL_ERROR_TYPE_DOMAIN_TO_ASCII: - error_str = ZSTR_INIT_LITERAL("DomainToAscii", false); + error_str = "DomainToAscii"; ZVAL_TRUE(&failure); break; case LXB_URL_ERROR_TYPE_DOMAIN_TO_UNICODE: - error_str = ZSTR_INIT_LITERAL("DomainToUnicode", false); + error_str = "DomainToUnicode"; ZVAL_FALSE(&failure); break; case LXB_URL_ERROR_TYPE_DOMAIN_INVALID_CODE_POINT: - error_str = ZSTR_INIT_LITERAL("DomainInvalidCodePoint", false); + error_str = "DomainInvalidCodePoint"; ZVAL_TRUE(&failure); break; case LXB_URL_ERROR_TYPE_HOST_INVALID_CODE_POINT: - error_str = ZSTR_INIT_LITERAL("HostInvalidCodePoint", false); + error_str = "HostInvalidCodePoint"; ZVAL_TRUE(&failure); break; case LXB_URL_ERROR_TYPE_IPV4_EMPTY_PART: - error_str = ZSTR_INIT_LITERAL("Ipv4EmptyPart", false); + error_str = "Ipv4EmptyPart"; ZVAL_FALSE(&failure); break; case LXB_URL_ERROR_TYPE_IPV4_TOO_MANY_PARTS: - error_str = ZSTR_INIT_LITERAL("Ipv4TooManyParts", false); + error_str = "Ipv4TooManyParts"; ZVAL_TRUE(&failure); break; case LXB_URL_ERROR_TYPE_IPV4_NON_NUMERIC_PART: - error_str = ZSTR_INIT_LITERAL("Ipv4NonNumericPart", false); + error_str = "Ipv4NonNumericPart"; ZVAL_TRUE(&failure); break; case LXB_URL_ERROR_TYPE_IPV4_NON_DECIMAL_PART: - error_str = ZSTR_INIT_LITERAL("Ipv4NonDecimalPart", false); + error_str = "Ipv4NonDecimalPart"; ZVAL_FALSE(&failure); break; case LXB_URL_ERROR_TYPE_IPV4_OUT_OF_RANGE_PART: - error_str = ZSTR_INIT_LITERAL("Ipv4OutOfRangePart", false); + error_str = "Ipv4OutOfRangePart"; ZVAL_TRUE(&failure); break; case LXB_URL_ERROR_TYPE_IPV6_UNCLOSED: - error_str = ZSTR_INIT_LITERAL("Ipv6Unclosed", false); + error_str = "Ipv6Unclosed"; ZVAL_TRUE(&failure); break; case LXB_URL_ERROR_TYPE_IPV6_INVALID_COMPRESSION: - error_str = ZSTR_INIT_LITERAL("Ipv6InvalidCompression", false); + error_str = "Ipv6InvalidCompression"; ZVAL_TRUE(&failure); break; case LXB_URL_ERROR_TYPE_IPV6_TOO_MANY_PIECES: - error_str = ZSTR_INIT_LITERAL("Ipv6TooManyPieces", false); + error_str = "Ipv6TooManyPieces"; ZVAL_TRUE(&failure); break; case LXB_URL_ERROR_TYPE_IPV6_MULTIPLE_COMPRESSION: - error_str = ZSTR_INIT_LITERAL("Ipv6MultipleCompression", false); + error_str = "Ipv6MultipleCompression"; ZVAL_TRUE(&failure); break; case LXB_URL_ERROR_TYPE_IPV6_INVALID_CODE_POINT: - error_str = ZSTR_INIT_LITERAL("Ipv6InvalidCodePoint", false); + error_str = "Ipv6InvalidCodePoint"; ZVAL_TRUE(&failure); break; case LXB_URL_ERROR_TYPE_IPV6_TOO_FEW_PIECES: - error_str = ZSTR_INIT_LITERAL("Ipv6TooFewPieces", false); + error_str = "Ipv6TooFewPieces"; ZVAL_TRUE(&failure); break; case LXB_URL_ERROR_TYPE_IPV4_IN_IPV6_TOO_MANY_PIECES: - error_str = ZSTR_INIT_LITERAL("Ipv4InIpv6TooManyPieces", false); + error_str = "Ipv4InIpv6TooManyPieces"; ZVAL_TRUE(&failure); break; case LXB_URL_ERROR_TYPE_IPV4_IN_IPV6_INVALID_CODE_POINT: - error_str = ZSTR_INIT_LITERAL("Ipv4InIpv6InvalidCodePoint", false); + error_str = "Ipv4InIpv6InvalidCodePoint"; ZVAL_TRUE(&failure); break; case LXB_URL_ERROR_TYPE_IPV4_IN_IPV6_OUT_OF_RANGE_PART: - error_str = ZSTR_INIT_LITERAL("Ipv4InIpv6OutOfRangePart", false); + error_str = "Ipv4InIpv6OutOfRangePart"; ZVAL_TRUE(&failure); break; case LXB_URL_ERROR_TYPE_IPV4_IN_IPV6_TOO_FEW_PARTS: - error_str = ZSTR_INIT_LITERAL("Ipv4InIpv6TooFewParts", false); + error_str = "Ipv4InIpv6TooFewParts"; ZVAL_TRUE(&failure); break; case LXB_URL_ERROR_TYPE_INVALID_URL_UNIT: - error_str = ZSTR_INIT_LITERAL("InvalidUrlUnit", false); + error_str = "InvalidUrlUnit"; ZVAL_FALSE(&failure); break; case LXB_URL_ERROR_TYPE_SPECIAL_SCHEME_MISSING_FOLLOWING_SOLIDUS: - error_str = ZSTR_INIT_LITERAL("SpecialSchemeMissingFollowingSolidus", false); + error_str = "SpecialSchemeMissingFollowingSolidus"; ZVAL_FALSE(&failure); break; case LXB_URL_ERROR_TYPE_MISSING_SCHEME_NON_RELATIVE_URL: - error_str = ZSTR_INIT_LITERAL("MissingSchemeNonRelativeUrl", false); + error_str = "MissingSchemeNonRelativeUrl"; ZVAL_TRUE(&failure); break; case LXB_URL_ERROR_TYPE_INVALID_REVERSE_SOLIDUS: - error_str = ZSTR_INIT_LITERAL("InvalidReverseSoldius", false); + error_str = "InvalidReverseSoldius"; ZVAL_FALSE(&failure); break; case LXB_URL_ERROR_TYPE_INVALID_CREDENTIALS: - error_str = ZSTR_INIT_LITERAL("InvalidCredentials", false); + error_str = "InvalidCredentials"; ZVAL_FALSE(&failure); break; case LXB_URL_ERROR_TYPE_HOST_MISSING: - error_str = ZSTR_INIT_LITERAL("HostMissing", false); + error_str = "HostMissing"; ZVAL_TRUE(&failure); break; case LXB_URL_ERROR_TYPE_PORT_OUT_OF_RANGE: - error_str = ZSTR_INIT_LITERAL("PortOutOfRange", false); + error_str = "PortOutOfRange"; ZVAL_TRUE(&failure); break; case LXB_URL_ERROR_TYPE_PORT_INVALID: - error_str = ZSTR_INIT_LITERAL("PortInvalid", false); + error_str = "PortInvalid"; ZVAL_TRUE(&failure); break; case LXB_URL_ERROR_TYPE_FILE_INVALID_WINDOWS_DRIVE_LETTER: - error_str = ZSTR_INIT_LITERAL("FileInvalidWindowsDriveLetter", false); + error_str = "FileInvalidWindowsDriveLetter"; ZVAL_FALSE(&failure); break; case LXB_URL_ERROR_TYPE_FILE_INVALID_WINDOWS_DRIVE_LETTER_HOST: - error_str = ZSTR_INIT_LITERAL("FileInvalidWindowsDriveLetterHost", false); + error_str = "FileInvalidWindowsDriveLetterHost"; ZVAL_FALSE(&failure); break; EMPTY_SWITCH_DEFAULT_CASE() } zval error_type; - zend_enum_new(&error_type, uri_whatwg_url_validation_error_type_ce, error_str, NULL); + ZVAL_OBJ(&error_type, zend_enum_get_case_cstr(uri_whatwg_url_validation_error_type_ce, error_str)); zend_update_property_ex(uri_whatwg_url_validation_error_ce, Z_OBJ(error), ZSTR_KNOWN(ZEND_STR_TYPE), &error_type); - zend_string_release_ex(error_str, false); - zval_ptr_dtor(&error_type); zend_update_property(uri_whatwg_url_validation_error_ce, Z_OBJ(error), ZEND_STRL("failure"), &failure); @@ -236,14 +234,14 @@ static zend_string *fill_errors(zval *errors) static void throw_invalid_url_exception_during_write(zval *errors, const char *component) { - zend_string *reason = fill_errors(errors); + const char *reason = fill_errors(errors); zend_object *exception = zend_throw_exception_ex( uri_whatwg_invalid_url_exception_ce, 0, "The specified %s is malformed%s%s%s", component, reason ? " (" : "", - reason ? ZSTR_VAL(reason) : "", + reason ? reason : "", reason ? ")" : "" ); zend_update_property(exception->ce, exception, ZEND_STRL("errors"), errors); @@ -567,10 +565,10 @@ lxb_url_t *lexbor_parse_uri_ex(const zend_string *uri_str, const lxb_url_t *lexb lexbor_cleanup_parser(); lxb_url_t *url = lxb_url_parse(&lexbor_parser, lexbor_base_url, (unsigned char *) ZSTR_VAL(uri_str), ZSTR_LEN(uri_str)); - zend_string *reason = fill_errors(errors); + const char *reason = fill_errors(errors); if (url == NULL && !silent) { - zend_object *exception = zend_throw_exception_ex(uri_whatwg_invalid_url_exception_ce, 0, "The specified URI is malformed%s%s%s", reason ? " (" : "", reason ? ZSTR_VAL(reason) : "", reason ? ")" : ""); + zend_object *exception = zend_throw_exception_ex(uri_whatwg_invalid_url_exception_ce, 0, "The specified URI is malformed%s%s%s", reason ? " (" : "", reason ? reason : "", reason ? ")" : ""); zend_update_property(exception->ce, exception, ZEND_STRL("errors"), errors); } diff --git a/ext/uri/php_uri.c b/ext/uri/php_uri.c index 5b2e21b1625a3..f5a5b160bba06 100644 --- a/ext/uri/php_uri.c +++ b/ext/uri/php_uri.c @@ -25,12 +25,14 @@ #include "Zend/zend_enum.h" #include "ext/standard/info.h" -#include "php_uri.h" #include "php_uri_common.h" #include "php_lexbor.h" +#include "php_uriparser.h" #include "php_uri_arginfo.h" #include "uriparser/src/UriConfig.h" +zend_class_entry *uri_rfc3986_uri_ce; +zend_object_handlers uri_rfc3986_uri_object_handlers; zend_class_entry *uri_whatwg_url_ce; zend_object_handlers uri_whatwg_uri_object_handlers; zend_class_entry *uri_comparison_mode_ce; @@ -104,67 +106,6 @@ static HashTable *uri_get_debug_properties(zend_object *object) return result; } -PHP_METHOD(Uri_WhatWg_InvalidUrlException, __construct) -{ - zend_string *message = NULL; - zval *errors = NULL; - zend_long code = 0; - zval *previous = NULL; - - ZEND_PARSE_PARAMETERS_START(0, 4) - Z_PARAM_OPTIONAL - Z_PARAM_STR(message) - Z_PARAM_ARRAY(errors) - Z_PARAM_LONG(code) - Z_PARAM_OBJECT_OF_CLASS_OR_NULL(previous, zend_ce_throwable) - ZEND_PARSE_PARAMETERS_END(); - - if (zend_update_exception_properties(INTERNAL_FUNCTION_PARAM_PASSTHRU, message, code, previous) == FAILURE) { - RETURN_THROWS(); - } - - if (errors == NULL) { - zval tmp; - ZVAL_EMPTY_ARRAY(&tmp); - zend_update_property(uri_whatwg_invalid_url_exception_ce, Z_OBJ_P(ZEND_THIS), ZEND_STRL("errors"), &tmp); - } else { - zend_update_property(uri_whatwg_invalid_url_exception_ce, Z_OBJ_P(ZEND_THIS), ZEND_STRL("errors"), errors); - } - if (EG(exception)) { - RETURN_THROWS(); - } -} - -PHP_METHOD(Uri_WhatWg_UrlValidationError, __construct) -{ - zend_string *context; - zval *type; - bool failure; - - ZEND_PARSE_PARAMETERS_START(3, 3) - Z_PARAM_STR(context) - Z_PARAM_OBJECT_OF_CLASS(type, uri_whatwg_url_validation_error_type_ce) - Z_PARAM_BOOL(failure) - ZEND_PARSE_PARAMETERS_END(); - - zend_update_property_str(uri_whatwg_url_validation_error_ce, Z_OBJ_P(ZEND_THIS), ZEND_STRL("context"), context); - if (EG(exception)) { - RETURN_THROWS(); - } - - zend_update_property_ex(uri_whatwg_url_validation_error_ce, Z_OBJ_P(ZEND_THIS), ZSTR_KNOWN(ZEND_STR_TYPE), type); - if (EG(exception)) { - RETURN_THROWS(); - } - - zval failure_zv; - ZVAL_BOOL(&failure_zv, failure); - zend_update_property(uri_whatwg_url_validation_error_ce, Z_OBJ_P(ZEND_THIS), ZEND_STRL("failure"), &failure_zv); - if (EG(exception)) { - RETURN_THROWS(); - } -} - /** * Pass the errors parameter by ref to errors_zv for userland, and frees it if * it is not not needed anymore. @@ -242,6 +183,91 @@ PHPAPI void php_uri_instantiate_uri( uri_object->internal.uri = uri; } +static void create_rfc3986_uri(INTERNAL_FUNCTION_PARAMETERS, bool is_constructor) +{ + zend_string *uri_str; + zend_object *base_url_object = NULL; + + ZEND_PARSE_PARAMETERS_START(1, 2) + Z_PARAM_PATH_STR(uri_str) + Z_PARAM_OPTIONAL + Z_PARAM_OBJ_OF_CLASS_OR_NULL(base_url_object, uri_rfc3986_uri_ce) + ZEND_PARSE_PARAMETERS_END(); + + php_uri_instantiate_uri(INTERNAL_FUNCTION_PARAM_PASSTHRU, &uriparser_uri_handler, uri_str, base_url_object, is_constructor, is_constructor, NULL); +} + +PHP_METHOD(Uri_Rfc3986_Uri, parse) +{ + create_rfc3986_uri(INTERNAL_FUNCTION_PARAM_PASSTHRU, false); +} + +PHP_METHOD(Uri_Rfc3986_Uri, __construct) +{ + create_rfc3986_uri(INTERNAL_FUNCTION_PARAM_PASSTHRU, true); +} + +PHP_METHOD(Uri_WhatWg_InvalidUrlException, __construct) +{ + zend_string *message = NULL; + zval *errors = NULL; + zend_long code = 0; + zval *previous = NULL; + + ZEND_PARSE_PARAMETERS_START(0, 4) + Z_PARAM_OPTIONAL + Z_PARAM_STR(message) + Z_PARAM_ARRAY(errors) + Z_PARAM_LONG(code) + Z_PARAM_OBJECT_OF_CLASS_OR_NULL(previous, zend_ce_throwable) + ZEND_PARSE_PARAMETERS_END(); + + if (zend_update_exception_properties(INTERNAL_FUNCTION_PARAM_PASSTHRU, message, code, previous) == FAILURE) { + RETURN_THROWS(); + } + + if (errors == NULL) { + zval tmp; + ZVAL_EMPTY_ARRAY(&tmp); + zend_update_property(uri_whatwg_invalid_url_exception_ce, Z_OBJ_P(ZEND_THIS), ZEND_STRL("errors"), &tmp); + } else { + zend_update_property(uri_whatwg_invalid_url_exception_ce, Z_OBJ_P(ZEND_THIS), ZEND_STRL("errors"), errors); + } + if (EG(exception)) { + RETURN_THROWS(); + } +} + +PHP_METHOD(Uri_WhatWg_UrlValidationError, __construct) +{ + zend_string *context; + zval *type; + bool failure; + + ZEND_PARSE_PARAMETERS_START(3, 3) + Z_PARAM_STR(context) + Z_PARAM_OBJECT_OF_CLASS(type, uri_whatwg_url_validation_error_type_ce) + Z_PARAM_BOOL(failure) + ZEND_PARSE_PARAMETERS_END(); + + zend_update_property_str(uri_whatwg_url_validation_error_ce, Z_OBJ_P(ZEND_THIS), ZEND_STRL("context"), context); + if (EG(exception)) { + RETURN_THROWS(); + } + + zend_update_property_ex(uri_whatwg_url_validation_error_ce, Z_OBJ_P(ZEND_THIS), ZSTR_KNOWN(ZEND_STR_TYPE), type); + if (EG(exception)) { + RETURN_THROWS(); + } + + zval failure_zv; + ZVAL_BOOL(&failure_zv, failure); + zend_update_property(uri_whatwg_url_validation_error_ce, Z_OBJ_P(ZEND_THIS), ZEND_STRL("failure"), &failure_zv); + if (EG(exception)) { + RETURN_THROWS(); + } +} + static void create_whatwg_uri(INTERNAL_FUNCTION_PARAMETERS, bool is_constructor) { zend_string *uri_str; @@ -268,6 +294,109 @@ PHP_METHOD(Uri_WhatWg_Url, __construct) create_whatwg_uri(INTERNAL_FUNCTION_PARAM_PASSTHRU, true); } +PHP_METHOD(Uri_Rfc3986_Uri, getScheme) +{ + uri_read_component(INTERNAL_FUNCTION_PARAM_PASSTHRU, URI_PROPERTY_NAME_SCHEME, URI_COMPONENT_READ_NORMALIZED_ASCII); +} + +PHP_METHOD(Uri_Rfc3986_Uri, getRawScheme) +{ + uri_read_component(INTERNAL_FUNCTION_PARAM_PASSTHRU, URI_PROPERTY_NAME_SCHEME, URI_COMPONENT_READ_RAW); +} + +static void read_uriparser_userinfo(INTERNAL_FUNCTION_PARAMETERS, uri_component_read_mode_t read_mode) +{ + ZEND_PARSE_PARAMETERS_NONE(); + + uri_internal_t *internal_uri = Z_URI_INTERNAL_P(ZEND_THIS); + URI_ASSERT_INITIALIZATION(internal_uri); + + if (UNEXPECTED(uriparser_read_userinfo(internal_uri, read_mode, return_value) == FAILURE)) { + zend_throw_error(NULL, "The userinfo component cannot be retrieved"); + RETURN_THROWS(); + } +} + +PHP_METHOD(Uri_Rfc3986_Uri, getUserInfo) +{ + read_uriparser_userinfo(INTERNAL_FUNCTION_PARAM_PASSTHRU, URI_COMPONENT_READ_NORMALIZED_ASCII); +} + +PHP_METHOD(Uri_Rfc3986_Uri, getRawUserInfo) +{ + read_uriparser_userinfo(INTERNAL_FUNCTION_PARAM_PASSTHRU, URI_COMPONENT_READ_RAW); +} + +PHP_METHOD(Uri_Rfc3986_Uri, getUsername) +{ + uri_read_component(INTERNAL_FUNCTION_PARAM_PASSTHRU, URI_PROPERTY_NAME_USERNAME, URI_COMPONENT_READ_NORMALIZED_ASCII); +} + +PHP_METHOD(Uri_Rfc3986_Uri, getRawUsername) +{ + uri_read_component(INTERNAL_FUNCTION_PARAM_PASSTHRU, URI_PROPERTY_NAME_USERNAME, URI_COMPONENT_READ_RAW); +} + +PHP_METHOD(Uri_Rfc3986_Uri, getPassword) +{ + uri_read_component(INTERNAL_FUNCTION_PARAM_PASSTHRU, URI_PROPERTY_NAME_PASSWORD, URI_COMPONENT_READ_NORMALIZED_ASCII); +} + +PHP_METHOD(Uri_Rfc3986_Uri, getRawPassword) +{ + uri_read_component(INTERNAL_FUNCTION_PARAM_PASSTHRU, URI_PROPERTY_NAME_PASSWORD, URI_COMPONENT_READ_RAW); +} + +PHP_METHOD(Uri_Rfc3986_Uri, getHost) +{ + uri_read_component(INTERNAL_FUNCTION_PARAM_PASSTHRU, URI_PROPERTY_NAME_HOST, URI_COMPONENT_READ_NORMALIZED_ASCII); +} + +PHP_METHOD(Uri_Rfc3986_Uri, getRawHost) +{ + uri_read_component(INTERNAL_FUNCTION_PARAM_PASSTHRU, URI_PROPERTY_NAME_HOST, URI_COMPONENT_READ_RAW); +} + +PHP_METHOD(Uri_Rfc3986_Uri, getPort) +{ + uri_read_component(INTERNAL_FUNCTION_PARAM_PASSTHRU, URI_PROPERTY_NAME_PORT, URI_COMPONENT_READ_NORMALIZED_ASCII); +} + +PHP_METHOD(Uri_Rfc3986_Uri, getPath) +{ + uri_read_component(INTERNAL_FUNCTION_PARAM_PASSTHRU, URI_PROPERTY_NAME_PATH, URI_COMPONENT_READ_NORMALIZED_ASCII); +} + +PHP_METHOD(Uri_Rfc3986_Uri, getRawPath) +{ + uri_read_component(INTERNAL_FUNCTION_PARAM_PASSTHRU, URI_PROPERTY_NAME_PATH, URI_COMPONENT_READ_RAW); +} + +PHP_METHOD(Uri_Rfc3986_Uri, getQuery) +{ + uri_read_component(INTERNAL_FUNCTION_PARAM_PASSTHRU, URI_PROPERTY_NAME_QUERY, URI_COMPONENT_READ_NORMALIZED_ASCII); +} + +PHP_METHOD(Uri_Rfc3986_Uri, getRawQuery) +{ + uri_read_component(INTERNAL_FUNCTION_PARAM_PASSTHRU, URI_PROPERTY_NAME_QUERY, URI_COMPONENT_READ_RAW); +} + +PHP_METHOD(Uri_Rfc3986_Uri, getFragment) +{ + uri_read_component(INTERNAL_FUNCTION_PARAM_PASSTHRU, URI_PROPERTY_NAME_FRAGMENT, URI_COMPONENT_READ_NORMALIZED_ASCII); +} + +PHP_METHOD(Uri_Rfc3986_Uri, getRawFragment) +{ + uri_read_component(INTERNAL_FUNCTION_PARAM_PASSTHRU, URI_PROPERTY_NAME_FRAGMENT, URI_COMPONENT_READ_RAW); +} + +static void throw_cannot_recompose_uri_to_string(zend_object *object) +{ + zend_throw_exception_ex(NULL, 0, "Cannot recompose %s to a string", ZSTR_VAL(object->ce->name)); +} + static void uri_equals(INTERNAL_FUNCTION_PARAMETERS, zend_object *that_object, zend_object *comparison_mode) { zend_object *this_object = Z_OBJ_P(ZEND_THIS); @@ -293,7 +422,7 @@ static void uri_equals(INTERNAL_FUNCTION_PARAMETERS, zend_object *that_object, z zend_string *this_str = this_internal_uri->handler->uri_to_string( this_internal_uri->uri, URI_RECOMPOSITION_NORMALIZED_ASCII, exclude_fragment); if (this_str == NULL) { - zend_throw_exception_ex(NULL, 0, "Cannot recompose %s to string", ZSTR_VAL(this_object->ce->name)); + throw_cannot_recompose_uri_to_string(this_object); RETURN_THROWS(); } @@ -301,7 +430,7 @@ static void uri_equals(INTERNAL_FUNCTION_PARAMETERS, zend_object *that_object, z that_internal_uri->uri, URI_RECOMPOSITION_NORMALIZED_ASCII, exclude_fragment); if (that_str == NULL) { zend_string_release(this_str); - zend_throw_exception_ex(NULL, 0, "Cannot recompose %s to string", ZSTR_VAL(that_object->ce->name)); + throw_cannot_recompose_uri_to_string(that_object); RETURN_THROWS(); } @@ -311,6 +440,99 @@ static void uri_equals(INTERNAL_FUNCTION_PARAMETERS, zend_object *that_object, z zend_string_release(that_str); } +PHP_METHOD(Uri_Rfc3986_Uri, equals) +{ + zend_object *that_object; + zend_object *comparison_mode = NULL; + + ZEND_PARSE_PARAMETERS_START(1, 2) + Z_PARAM_OBJ_OF_CLASS(that_object, uri_rfc3986_uri_ce) + Z_PARAM_OPTIONAL + Z_PARAM_OBJ_OF_CLASS(comparison_mode, uri_comparison_mode_ce) + ZEND_PARSE_PARAMETERS_END(); + + uri_equals(INTERNAL_FUNCTION_PARAM_PASSTHRU, that_object, comparison_mode); +} + +PHP_METHOD(Uri_Rfc3986_Uri, toRawString) +{ + ZEND_PARSE_PARAMETERS_NONE(); + + zend_object *this_object = Z_OBJ_P(ZEND_THIS); + uri_internal_t *internal_uri = uri_internal_from_obj(this_object); + URI_ASSERT_INITIALIZATION(internal_uri); + + zend_string *uri_str = internal_uri->handler->uri_to_string(internal_uri->uri, URI_RECOMPOSITION_RAW_ASCII, false); + if (uri_str == NULL) { + throw_cannot_recompose_uri_to_string(this_object); + RETURN_THROWS(); + } + + RETURN_STR(uri_str); +} + +PHP_METHOD(Uri_Rfc3986_Uri, toString) +{ + ZEND_PARSE_PARAMETERS_NONE(); + + zend_object *this_object = Z_OBJ_P(ZEND_THIS); + uri_internal_t *internal_uri = uri_internal_from_obj(this_object); + URI_ASSERT_INITIALIZATION(internal_uri); + + zend_string *uri_str = internal_uri->handler->uri_to_string(internal_uri->uri, URI_RECOMPOSITION_NORMALIZED_ASCII, false); + if (uri_str == NULL) { + throw_cannot_recompose_uri_to_string(this_object); + RETURN_THROWS(); + } + + RETURN_STR(uri_str); +} + +PHP_METHOD(Uri_Rfc3986_Uri, resolve) +{ + zend_string *uri_str; + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_PATH_STR(uri_str) + ZEND_PARSE_PARAMETERS_END(); + + zend_object *this_object = Z_OBJ_P(ZEND_THIS); + uri_internal_t *internal_uri = uri_internal_from_obj(this_object); + URI_ASSERT_INITIALIZATION(internal_uri); + + php_uri_instantiate_uri(INTERNAL_FUNCTION_PARAM_PASSTHRU, internal_uri->handler, uri_str, this_object, true, false, NULL); +} + +PHP_METHOD(Uri_Rfc3986_Uri, __serialize) +{ + ZEND_PARSE_PARAMETERS_NONE(); + + zend_object *this_object = Z_OBJ_P(ZEND_THIS); + uri_internal_t *internal_uri = uri_internal_from_obj(this_object); + URI_ASSERT_INITIALIZATION(internal_uri); + + /* Serialize state: "uri" key in the first array */ + zend_string *uri_str = internal_uri->handler->uri_to_string(internal_uri->uri, URI_RECOMPOSITION_RAW_ASCII, false); + if (uri_str == NULL) { + throw_cannot_recompose_uri_to_string(this_object); + RETURN_THROWS(); + } + zval tmp; + ZVAL_STR(&tmp, uri_str); + + array_init(return_value); + + zval arr; + array_init(&arr); + zend_hash_str_add_new(Z_ARRVAL(arr), URI_SERIALIZED_PROPERTY_NAME, sizeof(URI_SERIALIZED_PROPERTY_NAME) - 1, &tmp); + zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &arr); + + /* Serialize regular properties: second array */ + ZVAL_ARR(&arr, this_object->handlers->get_properties(this_object)); + Z_TRY_ADDREF(arr); + zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &arr); +} + static void uri_unserialize(INTERNAL_FUNCTION_PARAMETERS, const char *handler_name) { HashTable *data; @@ -371,29 +593,33 @@ static void uri_unserialize(INTERNAL_FUNCTION_PARAMETERS, const char *handler_na } } -PHP_METHOD(Uri_WhatWg_Url, getScheme) +PHP_METHOD(Uri_Rfc3986_Uri, __unserialize) { - uri_read_component(INTERNAL_FUNCTION_PARAM_PASSTHRU, URI_PROPERTY_NAME_SCHEME, URI_COMPONENT_READ_NORMALIZED_ASCII); + uri_unserialize(INTERNAL_FUNCTION_PARAM_PASSTHRU, URI_PARSER_RFC3986); } -PHP_METHOD(Uri_WhatWg_Url, withScheme) +PHP_METHOD(Uri_Rfc3986_Uri, __debugInfo) { - uri_write_component_str(INTERNAL_FUNCTION_PARAM_PASSTHRU, URI_PROPERTY_NAME_SCHEME); + ZEND_PARSE_PARAMETERS_NONE(); + + zend_object *object = Z_OBJ_P(ZEND_THIS); + + RETURN_ARR(uri_get_debug_properties(object)); } -PHP_METHOD(Uri_WhatWg_Url, getUsername) +PHP_METHOD(Uri_WhatWg_Url, getScheme) { - uri_read_component(INTERNAL_FUNCTION_PARAM_PASSTHRU, URI_PROPERTY_NAME_USERNAME, URI_COMPONENT_READ_NORMALIZED_ASCII); + uri_read_component(INTERNAL_FUNCTION_PARAM_PASSTHRU, URI_PROPERTY_NAME_SCHEME, URI_COMPONENT_READ_NORMALIZED_ASCII); } -PHP_METHOD(Uri_WhatWg_Url, withUsername) +PHP_METHOD(Uri_WhatWg_Url, withScheme) { - uri_write_component_str_or_null(INTERNAL_FUNCTION_PARAM_PASSTHRU, URI_PROPERTY_NAME_USERNAME); + uri_write_component_str(INTERNAL_FUNCTION_PARAM_PASSTHRU, URI_PROPERTY_NAME_SCHEME); } -PHP_METHOD(Uri_WhatWg_Url, getPassword) +PHP_METHOD(Uri_WhatWg_Url, withUsername) { - uri_read_component(INTERNAL_FUNCTION_PARAM_PASSTHRU, URI_PROPERTY_NAME_PASSWORD, URI_COMPONENT_READ_NORMALIZED_ASCII); + uri_write_component_str_or_null(INTERNAL_FUNCTION_PARAM_PASSTHRU, URI_PROPERTY_NAME_USERNAME); } PHP_METHOD(Uri_WhatWg_Url, withPassword) @@ -416,41 +642,21 @@ PHP_METHOD(Uri_WhatWg_Url, withHost) uri_write_component_str_or_null(INTERNAL_FUNCTION_PARAM_PASSTHRU, URI_PROPERTY_NAME_HOST); } -PHP_METHOD(Uri_WhatWg_Url, getPort) -{ - uri_read_component(INTERNAL_FUNCTION_PARAM_PASSTHRU, URI_PROPERTY_NAME_PORT, URI_COMPONENT_READ_NORMALIZED_ASCII); -} - PHP_METHOD(Uri_WhatWg_Url, withPort) { uri_write_component_long_or_null(INTERNAL_FUNCTION_PARAM_PASSTHRU, URI_PROPERTY_NAME_PORT); } -PHP_METHOD(Uri_WhatWg_Url, getPath) -{ - uri_read_component(INTERNAL_FUNCTION_PARAM_PASSTHRU, URI_PROPERTY_NAME_PATH, URI_COMPONENT_READ_NORMALIZED_ASCII); -} - PHP_METHOD(Uri_WhatWg_Url, withPath) { uri_write_component_str(INTERNAL_FUNCTION_PARAM_PASSTHRU, URI_PROPERTY_NAME_PATH); } -PHP_METHOD(Uri_WhatWg_Url, getQuery) -{ - uri_read_component(INTERNAL_FUNCTION_PARAM_PASSTHRU, URI_PROPERTY_NAME_QUERY, URI_COMPONENT_READ_NORMALIZED_ASCII); -} - PHP_METHOD(Uri_WhatWg_Url, withQuery) { uri_write_component_str_or_null(INTERNAL_FUNCTION_PARAM_PASSTHRU, URI_PROPERTY_NAME_QUERY); } -PHP_METHOD(Uri_WhatWg_Url, getFragment) -{ - uri_read_component(INTERNAL_FUNCTION_PARAM_PASSTHRU, URI_PROPERTY_NAME_FRAGMENT, URI_COMPONENT_READ_NORMALIZED_ASCII); -} - PHP_METHOD(Uri_WhatWg_Url, withFragment) { uri_write_component_str_or_null(INTERNAL_FUNCTION_PARAM_PASSTHRU, URI_PROPERTY_NAME_FRAGMENT); @@ -521,7 +727,7 @@ PHP_METHOD(Uri_WhatWg_Url, __serialize) /* Serialize state: "uri" key in the first array */ zend_string *uri_str = internal_uri->handler->uri_to_string(internal_uri->uri, URI_RECOMPOSITION_RAW_ASCII, false); if (uri_str == NULL) { - zend_throw_exception_ex(NULL, 0, "Cannot recompose %s to string", ZSTR_VAL(this_object->ce->name)); + throw_cannot_recompose_uri_to_string(this_object); RETURN_THROWS(); } zval tmp; @@ -629,6 +835,9 @@ zend_result uri_handler_register(const uri_handler_t *uri_handler) static PHP_MINIT_FUNCTION(uri) { + uri_rfc3986_uri_ce = register_class_Uri_Rfc3986_Uri(); + php_uri_implementation_set_object_handlers(uri_rfc3986_uri_ce, &uri_rfc3986_uri_object_handlers); + uri_whatwg_url_ce = register_class_Uri_WhatWg_Url(); php_uri_implementation_set_object_handlers(uri_whatwg_url_ce, &uri_whatwg_uri_object_handlers); @@ -641,6 +850,10 @@ static PHP_MINIT_FUNCTION(uri) zend_hash_init(&uri_handlers, 4, NULL, NULL, true); + if (PHP_MINIT(uri_uriparser)(INIT_FUNC_ARGS_PASSTHRU) == FAILURE) { + return FAILURE; + } + if (uri_handler_register(&lexbor_uri_handler) == FAILURE) { return FAILURE; } diff --git a/ext/uri/php_uri.stub.php b/ext/uri/php_uri.stub.php index ef49e4ba6f968..9fbd40d98e5e9 100644 --- a/ext/uri/php_uri.stub.php +++ b/ext/uri/php_uri.stub.php @@ -20,6 +20,64 @@ enum UriComparisonMode } } +namespace Uri\Rfc3986 { + /** @strict-properties */ + final readonly class Uri + { + public static function parse(string $uri, ?\Uri\Rfc3986\Uri $baseUrl = null): ?static {} + + public function __construct(string $uri, ?\Uri\Rfc3986\Uri $baseUrl = null) {} + + public function getScheme(): ?string {} + + public function getRawScheme(): ?string {} + + public function getUserInfo(): ?string {} + + public function getRawUserInfo(): ?string {} + + public function getUsername(): ?string {} + + public function getRawUsername(): ?string {} + + public function getPassword(): ?string {} + + public function getRawPassword(): ?string {} + + public function getHost(): ?string {} + + public function getRawHost(): ?string {} + + public function getPort(): ?int {} + + public function getPath(): string {} + + public function getRawPath(): string {} + + public function getQuery(): ?string {} + + public function getRawQuery(): ?string {} + + public function getFragment(): ?string {} + + public function getRawFragment(): ?string {} + + public function equals(\Uri\Rfc3986\Uri $uri, \Uri\UriComparisonMode $comparisonMode = \Uri\UriComparisonMode::ExcludeFragment): bool {} + + public function toString(): string {} + + public function toRawString(): string {} + + public function resolve(string $uri): static {} + + public function __serialize(): array {} + + public function __unserialize(array $data): void {} + + public function __debugInfo(): array {} + } +} + namespace Uri\WhatWg { /** @strict-properties */ class InvalidUrlException extends \Uri\InvalidUriException @@ -85,10 +143,12 @@ public function getScheme(): string {} public function withScheme(string $scheme): static {} + /** @implementation-alias Uri\Rfc3986\Uri::getUsername */ public function getUsername(): ?string {} public function withUsername(?string $username): static {} + /** @implementation-alias Uri\Rfc3986\Uri::getPassword */ public function getPassword(): ?string {} public function withPassword(#[\SensitiveParameter] ?string $password): static {} @@ -99,18 +159,22 @@ public function getUnicodeHost(): ?string {} public function withHost(?string $host): static {} + /** @implementation-alias Uri\Rfc3986\Uri::getPort */ public function getPort(): ?int {} public function withPort(?int $port): static {} + /** @implementation-alias Uri\Rfc3986\Uri::getPath */ public function getPath(): string {} public function withPath(string $path): static {} + /** @implementation-alias Uri\Rfc3986\Uri::getQuery */ public function getQuery(): ?string {} public function withQuery(?string $query): static {} + /** @implementation-alias Uri\Rfc3986\Uri::getFragment */ public function getFragment(): ?string {} public function withFragment(?string $fragment): static {} diff --git a/ext/uri/php_uri_arginfo.h b/ext/uri/php_uri_arginfo.h index 0ae755a9f70dc..65630f113a3d3 100644 --- a/ext/uri/php_uri_arginfo.h +++ b/ext/uri/php_uri_arginfo.h @@ -1,5 +1,74 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 1945c28deef13c2af552b18c2a5a6c7798d4aeec */ + * Stub hash: e2c448000b1e00485bc988f073ea61dfc984e953 */ + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Uri_Rfc3986_Uri_parse, 0, 1, IS_STATIC, 1) + ZEND_ARG_TYPE_INFO(0, uri, IS_STRING, 0) + ZEND_ARG_OBJ_INFO_WITH_DEFAULT_VALUE(0, baseUrl, Uri\\Rfc3986\\\125ri, 1, "null") +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Uri_Rfc3986_Uri___construct, 0, 0, 1) + ZEND_ARG_TYPE_INFO(0, uri, IS_STRING, 0) + ZEND_ARG_OBJ_INFO_WITH_DEFAULT_VALUE(0, baseUrl, Uri\\Rfc3986\\\125ri, 1, "null") +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Uri_Rfc3986_Uri_getScheme, 0, 0, IS_STRING, 1) +ZEND_END_ARG_INFO() + +#define arginfo_class_Uri_Rfc3986_Uri_getRawScheme arginfo_class_Uri_Rfc3986_Uri_getScheme + +#define arginfo_class_Uri_Rfc3986_Uri_getUserInfo arginfo_class_Uri_Rfc3986_Uri_getScheme + +#define arginfo_class_Uri_Rfc3986_Uri_getRawUserInfo arginfo_class_Uri_Rfc3986_Uri_getScheme + +#define arginfo_class_Uri_Rfc3986_Uri_getUsername arginfo_class_Uri_Rfc3986_Uri_getScheme + +#define arginfo_class_Uri_Rfc3986_Uri_getRawUsername arginfo_class_Uri_Rfc3986_Uri_getScheme + +#define arginfo_class_Uri_Rfc3986_Uri_getPassword arginfo_class_Uri_Rfc3986_Uri_getScheme + +#define arginfo_class_Uri_Rfc3986_Uri_getRawPassword arginfo_class_Uri_Rfc3986_Uri_getScheme + +#define arginfo_class_Uri_Rfc3986_Uri_getHost arginfo_class_Uri_Rfc3986_Uri_getScheme + +#define arginfo_class_Uri_Rfc3986_Uri_getRawHost arginfo_class_Uri_Rfc3986_Uri_getScheme + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Uri_Rfc3986_Uri_getPort, 0, 0, IS_LONG, 1) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Uri_Rfc3986_Uri_getPath, 0, 0, IS_STRING, 0) +ZEND_END_ARG_INFO() + +#define arginfo_class_Uri_Rfc3986_Uri_getRawPath arginfo_class_Uri_Rfc3986_Uri_getPath + +#define arginfo_class_Uri_Rfc3986_Uri_getQuery arginfo_class_Uri_Rfc3986_Uri_getScheme + +#define arginfo_class_Uri_Rfc3986_Uri_getRawQuery arginfo_class_Uri_Rfc3986_Uri_getScheme + +#define arginfo_class_Uri_Rfc3986_Uri_getFragment arginfo_class_Uri_Rfc3986_Uri_getScheme + +#define arginfo_class_Uri_Rfc3986_Uri_getRawFragment arginfo_class_Uri_Rfc3986_Uri_getScheme + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Uri_Rfc3986_Uri_equals, 0, 1, _IS_BOOL, 0) + ZEND_ARG_OBJ_INFO(0, uri, Uri\\Rfc3986\\\125ri, 0) + ZEND_ARG_OBJ_INFO_WITH_DEFAULT_VALUE(0, comparisonMode, Uri\\\125riComparisonMode, 0, "Uri\\UriComparisonMode::ExcludeFragment") +ZEND_END_ARG_INFO() + +#define arginfo_class_Uri_Rfc3986_Uri_toString arginfo_class_Uri_Rfc3986_Uri_getPath + +#define arginfo_class_Uri_Rfc3986_Uri_toRawString arginfo_class_Uri_Rfc3986_Uri_getPath + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Uri_Rfc3986_Uri_resolve, 0, 1, IS_STATIC, 0) + ZEND_ARG_TYPE_INFO(0, uri, IS_STRING, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Uri_Rfc3986_Uri___serialize, 0, 0, IS_ARRAY, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Uri_Rfc3986_Uri___unserialize, 0, 1, IS_VOID, 0) + ZEND_ARG_TYPE_INFO(0, data, IS_ARRAY, 0) +ZEND_END_ARG_INFO() + +#define arginfo_class_Uri_Rfc3986_Uri___debugInfo arginfo_class_Uri_Rfc3986_Uri___serialize ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Uri_WhatWg_InvalidUrlException___construct, 0, 0, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, message, IS_STRING, 0, "\"\"") @@ -26,54 +95,51 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Uri_WhatWg_Url___construct, 0, 0, 1) ZEND_ARG_INFO_WITH_DEFAULT_VALUE(1, softErrors, "null") ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Uri_WhatWg_Url_getScheme, 0, 0, IS_STRING, 0) -ZEND_END_ARG_INFO() +#define arginfo_class_Uri_WhatWg_Url_getScheme arginfo_class_Uri_Rfc3986_Uri_getPath ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Uri_WhatWg_Url_withScheme, 0, 1, IS_STATIC, 0) ZEND_ARG_TYPE_INFO(0, scheme, IS_STRING, 0) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Uri_WhatWg_Url_getUsername, 0, 0, IS_STRING, 1) -ZEND_END_ARG_INFO() +#define arginfo_class_Uri_WhatWg_Url_getUsername arginfo_class_Uri_Rfc3986_Uri_getScheme ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Uri_WhatWg_Url_withUsername, 0, 1, IS_STATIC, 0) ZEND_ARG_TYPE_INFO(0, username, IS_STRING, 1) ZEND_END_ARG_INFO() -#define arginfo_class_Uri_WhatWg_Url_getPassword arginfo_class_Uri_WhatWg_Url_getUsername +#define arginfo_class_Uri_WhatWg_Url_getPassword arginfo_class_Uri_Rfc3986_Uri_getScheme ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Uri_WhatWg_Url_withPassword, 0, 1, IS_STATIC, 0) ZEND_ARG_TYPE_INFO(0, password, IS_STRING, 1) ZEND_END_ARG_INFO() -#define arginfo_class_Uri_WhatWg_Url_getAsciiHost arginfo_class_Uri_WhatWg_Url_getUsername +#define arginfo_class_Uri_WhatWg_Url_getAsciiHost arginfo_class_Uri_Rfc3986_Uri_getScheme -#define arginfo_class_Uri_WhatWg_Url_getUnicodeHost arginfo_class_Uri_WhatWg_Url_getUsername +#define arginfo_class_Uri_WhatWg_Url_getUnicodeHost arginfo_class_Uri_Rfc3986_Uri_getScheme ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Uri_WhatWg_Url_withHost, 0, 1, IS_STATIC, 0) ZEND_ARG_TYPE_INFO(0, host, IS_STRING, 1) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Uri_WhatWg_Url_getPort, 0, 0, IS_LONG, 1) -ZEND_END_ARG_INFO() +#define arginfo_class_Uri_WhatWg_Url_getPort arginfo_class_Uri_Rfc3986_Uri_getPort ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Uri_WhatWg_Url_withPort, 0, 1, IS_STATIC, 0) ZEND_ARG_TYPE_INFO(0, port, IS_LONG, 1) ZEND_END_ARG_INFO() -#define arginfo_class_Uri_WhatWg_Url_getPath arginfo_class_Uri_WhatWg_Url_getScheme +#define arginfo_class_Uri_WhatWg_Url_getPath arginfo_class_Uri_Rfc3986_Uri_getPath ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Uri_WhatWg_Url_withPath, 0, 1, IS_STATIC, 0) ZEND_ARG_TYPE_INFO(0, path, IS_STRING, 0) ZEND_END_ARG_INFO() -#define arginfo_class_Uri_WhatWg_Url_getQuery arginfo_class_Uri_WhatWg_Url_getUsername +#define arginfo_class_Uri_WhatWg_Url_getQuery arginfo_class_Uri_Rfc3986_Uri_getScheme ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Uri_WhatWg_Url_withQuery, 0, 1, IS_STATIC, 0) ZEND_ARG_TYPE_INFO(0, query, IS_STRING, 1) ZEND_END_ARG_INFO() -#define arginfo_class_Uri_WhatWg_Url_getFragment arginfo_class_Uri_WhatWg_Url_getUsername +#define arginfo_class_Uri_WhatWg_Url_getFragment arginfo_class_Uri_Rfc3986_Uri_getScheme ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Uri_WhatWg_Url_withFragment, 0, 1, IS_STATIC, 0) ZEND_ARG_TYPE_INFO(0, fragment, IS_STRING, 1) @@ -84,44 +150,61 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Uri_WhatWg_Url_equals, 0, ZEND_ARG_OBJ_INFO_WITH_DEFAULT_VALUE(0, comparisonMode, Uri\\\125riComparisonMode, 0, "Uri\\UriComparisonMode::ExcludeFragment") ZEND_END_ARG_INFO() -#define arginfo_class_Uri_WhatWg_Url_toAsciiString arginfo_class_Uri_WhatWg_Url_getScheme +#define arginfo_class_Uri_WhatWg_Url_toAsciiString arginfo_class_Uri_Rfc3986_Uri_getPath -#define arginfo_class_Uri_WhatWg_Url_toUnicodeString arginfo_class_Uri_WhatWg_Url_getScheme +#define arginfo_class_Uri_WhatWg_Url_toUnicodeString arginfo_class_Uri_Rfc3986_Uri_getPath ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Uri_WhatWg_Url_resolve, 0, 1, IS_STATIC, 0) ZEND_ARG_TYPE_INFO(0, uri, IS_STRING, 0) ZEND_ARG_INFO_WITH_DEFAULT_VALUE(1, softErrors, "null") ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Uri_WhatWg_Url___serialize, 0, 0, IS_ARRAY, 0) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Uri_WhatWg_Url___unserialize, 0, 1, IS_VOID, 0) - ZEND_ARG_TYPE_INFO(0, data, IS_ARRAY, 0) -ZEND_END_ARG_INFO() - -#define arginfo_class_Uri_WhatWg_Url___debugInfo arginfo_class_Uri_WhatWg_Url___serialize - +#define arginfo_class_Uri_WhatWg_Url___serialize arginfo_class_Uri_Rfc3986_Uri___serialize + +#define arginfo_class_Uri_WhatWg_Url___unserialize arginfo_class_Uri_Rfc3986_Uri___unserialize + +#define arginfo_class_Uri_WhatWg_Url___debugInfo arginfo_class_Uri_Rfc3986_Uri___serialize + +ZEND_METHOD(Uri_Rfc3986_Uri, parse); +ZEND_METHOD(Uri_Rfc3986_Uri, __construct); +ZEND_METHOD(Uri_Rfc3986_Uri, getScheme); +ZEND_METHOD(Uri_Rfc3986_Uri, getRawScheme); +ZEND_METHOD(Uri_Rfc3986_Uri, getUserInfo); +ZEND_METHOD(Uri_Rfc3986_Uri, getRawUserInfo); +ZEND_METHOD(Uri_Rfc3986_Uri, getUsername); +ZEND_METHOD(Uri_Rfc3986_Uri, getRawUsername); +ZEND_METHOD(Uri_Rfc3986_Uri, getPassword); +ZEND_METHOD(Uri_Rfc3986_Uri, getRawPassword); +ZEND_METHOD(Uri_Rfc3986_Uri, getHost); +ZEND_METHOD(Uri_Rfc3986_Uri, getRawHost); +ZEND_METHOD(Uri_Rfc3986_Uri, getPort); +ZEND_METHOD(Uri_Rfc3986_Uri, getPath); +ZEND_METHOD(Uri_Rfc3986_Uri, getRawPath); +ZEND_METHOD(Uri_Rfc3986_Uri, getQuery); +ZEND_METHOD(Uri_Rfc3986_Uri, getRawQuery); +ZEND_METHOD(Uri_Rfc3986_Uri, getFragment); +ZEND_METHOD(Uri_Rfc3986_Uri, getRawFragment); +ZEND_METHOD(Uri_Rfc3986_Uri, equals); +ZEND_METHOD(Uri_Rfc3986_Uri, toString); +ZEND_METHOD(Uri_Rfc3986_Uri, toRawString); +ZEND_METHOD(Uri_Rfc3986_Uri, resolve); +ZEND_METHOD(Uri_Rfc3986_Uri, __serialize); +ZEND_METHOD(Uri_Rfc3986_Uri, __unserialize); +ZEND_METHOD(Uri_Rfc3986_Uri, __debugInfo); ZEND_METHOD(Uri_WhatWg_InvalidUrlException, __construct); ZEND_METHOD(Uri_WhatWg_UrlValidationError, __construct); ZEND_METHOD(Uri_WhatWg_Url, parse); ZEND_METHOD(Uri_WhatWg_Url, __construct); ZEND_METHOD(Uri_WhatWg_Url, getScheme); ZEND_METHOD(Uri_WhatWg_Url, withScheme); -ZEND_METHOD(Uri_WhatWg_Url, getUsername); ZEND_METHOD(Uri_WhatWg_Url, withUsername); -ZEND_METHOD(Uri_WhatWg_Url, getPassword); ZEND_METHOD(Uri_WhatWg_Url, withPassword); ZEND_METHOD(Uri_WhatWg_Url, getAsciiHost); ZEND_METHOD(Uri_WhatWg_Url, getUnicodeHost); ZEND_METHOD(Uri_WhatWg_Url, withHost); -ZEND_METHOD(Uri_WhatWg_Url, getPort); ZEND_METHOD(Uri_WhatWg_Url, withPort); -ZEND_METHOD(Uri_WhatWg_Url, getPath); ZEND_METHOD(Uri_WhatWg_Url, withPath); -ZEND_METHOD(Uri_WhatWg_Url, getQuery); ZEND_METHOD(Uri_WhatWg_Url, withQuery); -ZEND_METHOD(Uri_WhatWg_Url, getFragment); ZEND_METHOD(Uri_WhatWg_Url, withFragment); ZEND_METHOD(Uri_WhatWg_Url, equals); ZEND_METHOD(Uri_WhatWg_Url, toAsciiString); @@ -131,6 +214,36 @@ ZEND_METHOD(Uri_WhatWg_Url, __serialize); ZEND_METHOD(Uri_WhatWg_Url, __unserialize); ZEND_METHOD(Uri_WhatWg_Url, __debugInfo); +static const zend_function_entry class_Uri_Rfc3986_Uri_methods[] = { + ZEND_ME(Uri_Rfc3986_Uri, parse, arginfo_class_Uri_Rfc3986_Uri_parse, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) + ZEND_ME(Uri_Rfc3986_Uri, __construct, arginfo_class_Uri_Rfc3986_Uri___construct, ZEND_ACC_PUBLIC) + ZEND_ME(Uri_Rfc3986_Uri, getScheme, arginfo_class_Uri_Rfc3986_Uri_getScheme, ZEND_ACC_PUBLIC) + ZEND_ME(Uri_Rfc3986_Uri, getRawScheme, arginfo_class_Uri_Rfc3986_Uri_getRawScheme, ZEND_ACC_PUBLIC) + ZEND_ME(Uri_Rfc3986_Uri, getUserInfo, arginfo_class_Uri_Rfc3986_Uri_getUserInfo, ZEND_ACC_PUBLIC) + ZEND_ME(Uri_Rfc3986_Uri, getRawUserInfo, arginfo_class_Uri_Rfc3986_Uri_getRawUserInfo, ZEND_ACC_PUBLIC) + ZEND_ME(Uri_Rfc3986_Uri, getUsername, arginfo_class_Uri_Rfc3986_Uri_getUsername, ZEND_ACC_PUBLIC) + ZEND_ME(Uri_Rfc3986_Uri, getRawUsername, arginfo_class_Uri_Rfc3986_Uri_getRawUsername, ZEND_ACC_PUBLIC) + ZEND_ME(Uri_Rfc3986_Uri, getPassword, arginfo_class_Uri_Rfc3986_Uri_getPassword, ZEND_ACC_PUBLIC) + ZEND_ME(Uri_Rfc3986_Uri, getRawPassword, arginfo_class_Uri_Rfc3986_Uri_getRawPassword, ZEND_ACC_PUBLIC) + ZEND_ME(Uri_Rfc3986_Uri, getHost, arginfo_class_Uri_Rfc3986_Uri_getHost, ZEND_ACC_PUBLIC) + ZEND_ME(Uri_Rfc3986_Uri, getRawHost, arginfo_class_Uri_Rfc3986_Uri_getRawHost, ZEND_ACC_PUBLIC) + ZEND_ME(Uri_Rfc3986_Uri, getPort, arginfo_class_Uri_Rfc3986_Uri_getPort, ZEND_ACC_PUBLIC) + ZEND_ME(Uri_Rfc3986_Uri, getPath, arginfo_class_Uri_Rfc3986_Uri_getPath, ZEND_ACC_PUBLIC) + ZEND_ME(Uri_Rfc3986_Uri, getRawPath, arginfo_class_Uri_Rfc3986_Uri_getRawPath, ZEND_ACC_PUBLIC) + ZEND_ME(Uri_Rfc3986_Uri, getQuery, arginfo_class_Uri_Rfc3986_Uri_getQuery, ZEND_ACC_PUBLIC) + ZEND_ME(Uri_Rfc3986_Uri, getRawQuery, arginfo_class_Uri_Rfc3986_Uri_getRawQuery, ZEND_ACC_PUBLIC) + ZEND_ME(Uri_Rfc3986_Uri, getFragment, arginfo_class_Uri_Rfc3986_Uri_getFragment, ZEND_ACC_PUBLIC) + ZEND_ME(Uri_Rfc3986_Uri, getRawFragment, arginfo_class_Uri_Rfc3986_Uri_getRawFragment, ZEND_ACC_PUBLIC) + ZEND_ME(Uri_Rfc3986_Uri, equals, arginfo_class_Uri_Rfc3986_Uri_equals, ZEND_ACC_PUBLIC) + ZEND_ME(Uri_Rfc3986_Uri, toString, arginfo_class_Uri_Rfc3986_Uri_toString, ZEND_ACC_PUBLIC) + ZEND_ME(Uri_Rfc3986_Uri, toRawString, arginfo_class_Uri_Rfc3986_Uri_toRawString, ZEND_ACC_PUBLIC) + ZEND_ME(Uri_Rfc3986_Uri, resolve, arginfo_class_Uri_Rfc3986_Uri_resolve, ZEND_ACC_PUBLIC) + ZEND_ME(Uri_Rfc3986_Uri, __serialize, arginfo_class_Uri_Rfc3986_Uri___serialize, ZEND_ACC_PUBLIC) + ZEND_ME(Uri_Rfc3986_Uri, __unserialize, arginfo_class_Uri_Rfc3986_Uri___unserialize, ZEND_ACC_PUBLIC) + ZEND_ME(Uri_Rfc3986_Uri, __debugInfo, arginfo_class_Uri_Rfc3986_Uri___debugInfo, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + static const zend_function_entry class_Uri_WhatWg_InvalidUrlException_methods[] = { ZEND_ME(Uri_WhatWg_InvalidUrlException, __construct, arginfo_class_Uri_WhatWg_InvalidUrlException___construct, ZEND_ACC_PUBLIC) ZEND_FE_END @@ -146,20 +259,20 @@ static const zend_function_entry class_Uri_WhatWg_Url_methods[] = { ZEND_ME(Uri_WhatWg_Url, __construct, arginfo_class_Uri_WhatWg_Url___construct, ZEND_ACC_PUBLIC) ZEND_ME(Uri_WhatWg_Url, getScheme, arginfo_class_Uri_WhatWg_Url_getScheme, ZEND_ACC_PUBLIC) ZEND_ME(Uri_WhatWg_Url, withScheme, arginfo_class_Uri_WhatWg_Url_withScheme, ZEND_ACC_PUBLIC) - ZEND_ME(Uri_WhatWg_Url, getUsername, arginfo_class_Uri_WhatWg_Url_getUsername, ZEND_ACC_PUBLIC) + ZEND_RAW_FENTRY("getUsername", zim_Uri_Rfc3986_Uri_getUsername, arginfo_class_Uri_WhatWg_Url_getUsername, ZEND_ACC_PUBLIC, NULL, NULL) ZEND_ME(Uri_WhatWg_Url, withUsername, arginfo_class_Uri_WhatWg_Url_withUsername, ZEND_ACC_PUBLIC) - ZEND_ME(Uri_WhatWg_Url, getPassword, arginfo_class_Uri_WhatWg_Url_getPassword, ZEND_ACC_PUBLIC) + ZEND_RAW_FENTRY("getPassword", zim_Uri_Rfc3986_Uri_getPassword, arginfo_class_Uri_WhatWg_Url_getPassword, ZEND_ACC_PUBLIC, NULL, NULL) ZEND_ME(Uri_WhatWg_Url, withPassword, arginfo_class_Uri_WhatWg_Url_withPassword, ZEND_ACC_PUBLIC) ZEND_ME(Uri_WhatWg_Url, getAsciiHost, arginfo_class_Uri_WhatWg_Url_getAsciiHost, ZEND_ACC_PUBLIC) ZEND_ME(Uri_WhatWg_Url, getUnicodeHost, arginfo_class_Uri_WhatWg_Url_getUnicodeHost, ZEND_ACC_PUBLIC) ZEND_ME(Uri_WhatWg_Url, withHost, arginfo_class_Uri_WhatWg_Url_withHost, ZEND_ACC_PUBLIC) - ZEND_ME(Uri_WhatWg_Url, getPort, arginfo_class_Uri_WhatWg_Url_getPort, ZEND_ACC_PUBLIC) + ZEND_RAW_FENTRY("getPort", zim_Uri_Rfc3986_Uri_getPort, arginfo_class_Uri_WhatWg_Url_getPort, ZEND_ACC_PUBLIC, NULL, NULL) ZEND_ME(Uri_WhatWg_Url, withPort, arginfo_class_Uri_WhatWg_Url_withPort, ZEND_ACC_PUBLIC) - ZEND_ME(Uri_WhatWg_Url, getPath, arginfo_class_Uri_WhatWg_Url_getPath, ZEND_ACC_PUBLIC) + ZEND_RAW_FENTRY("getPath", zim_Uri_Rfc3986_Uri_getPath, arginfo_class_Uri_WhatWg_Url_getPath, ZEND_ACC_PUBLIC, NULL, NULL) ZEND_ME(Uri_WhatWg_Url, withPath, arginfo_class_Uri_WhatWg_Url_withPath, ZEND_ACC_PUBLIC) - ZEND_ME(Uri_WhatWg_Url, getQuery, arginfo_class_Uri_WhatWg_Url_getQuery, ZEND_ACC_PUBLIC) + ZEND_RAW_FENTRY("getQuery", zim_Uri_Rfc3986_Uri_getQuery, arginfo_class_Uri_WhatWg_Url_getQuery, ZEND_ACC_PUBLIC, NULL, NULL) ZEND_ME(Uri_WhatWg_Url, withQuery, arginfo_class_Uri_WhatWg_Url_withQuery, ZEND_ACC_PUBLIC) - ZEND_ME(Uri_WhatWg_Url, getFragment, arginfo_class_Uri_WhatWg_Url_getFragment, ZEND_ACC_PUBLIC) + ZEND_RAW_FENTRY("getFragment", zim_Uri_Rfc3986_Uri_getFragment, arginfo_class_Uri_WhatWg_Url_getFragment, ZEND_ACC_PUBLIC, NULL, NULL) ZEND_ME(Uri_WhatWg_Url, withFragment, arginfo_class_Uri_WhatWg_Url_withFragment, ZEND_ACC_PUBLIC) ZEND_ME(Uri_WhatWg_Url, equals, arginfo_class_Uri_WhatWg_Url_equals, ZEND_ACC_PUBLIC) ZEND_ME(Uri_WhatWg_Url, toAsciiString, arginfo_class_Uri_WhatWg_Url_toAsciiString, ZEND_ACC_PUBLIC) @@ -202,6 +315,16 @@ static zend_class_entry *register_class_Uri_UriComparisonMode(void) return class_entry; } +static zend_class_entry *register_class_Uri_Rfc3986_Uri(void) +{ + zend_class_entry ce, *class_entry; + + INIT_NS_CLASS_ENTRY(ce, "Uri\\Rfc3986", "Uri", class_Uri_Rfc3986_Uri_methods); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_READONLY_CLASS); + + return class_entry; +} + static zend_class_entry *register_class_Uri_WhatWg_InvalidUrlException(zend_class_entry *class_entry_Uri_InvalidUriException) { zend_class_entry ce, *class_entry; diff --git a/ext/uri/php_uri_common.c b/ext/uri/php_uri_common.c index 9128b942e57b8..29de370bd56b6 100644 --- a/ext/uri/php_uri_common.c +++ b/ext/uri/php_uri_common.c @@ -76,8 +76,7 @@ void uri_read_component(INTERNAL_FUNCTION_PARAMETERS, uri_property_name_t proper ZEND_ASSERT(property_handler != NULL); if (UNEXPECTED(property_handler->read_func(internal_uri, component_read_mode, return_value) == FAILURE)) { - zend_throw_error(NULL, "%s::$%s property cannot be retrieved", ZSTR_VAL(Z_OBJ_P(ZEND_THIS)->ce->name), - ZSTR_VAL(get_known_string_by_property_name(property_name))); + zend_throw_error(NULL, "The %s component cannot be retrieved", ZSTR_VAL(get_known_string_by_property_name(property_name))); RETURN_THROWS(); } } @@ -91,14 +90,11 @@ static void uri_write_component_ex(INTERNAL_FUNCTION_PARAMETERS, uri_property_na ZEND_ASSERT(property_handler != NULL); zend_object *new_object = uri_clone_obj_handler(Z_OBJ_P(ZEND_THIS)); - if (UNEXPECTED(EG(exception) != NULL)) { - zend_object_release(new_object); - RETURN_THROWS(); - } + ZEND_ASSERT(new_object != NULL); uri_internal_t *new_internal_uri = uri_internal_from_obj(new_object); URI_ASSERT_INITIALIZATION(new_internal_uri); - if (property_handler->write_func == NULL) { + if (UNEXPECTED(property_handler->write_func == NULL)) { zend_readonly_property_modification_error_ex(ZSTR_VAL(Z_OBJ_P(ZEND_THIS)->ce->name), ZSTR_VAL(get_known_string_by_property_name(property_name))); zend_object_release(new_object); @@ -107,7 +103,7 @@ static void uri_write_component_ex(INTERNAL_FUNCTION_PARAMETERS, uri_property_na zval errors; ZVAL_UNDEF(&errors); - if (property_handler->write_func(new_internal_uri, property_zv, &errors) == FAILURE) { + if (UNEXPECTED(property_handler->write_func(new_internal_uri, property_zv, &errors) == FAILURE)) { zval_ptr_dtor(&errors); zend_object_release(new_object); RETURN_THROWS(); diff --git a/ext/uri/php_uri_common.h b/ext/uri/php_uri_common.h index 1aee1cd512472..8e5b0c2d2279f 100644 --- a/ext/uri/php_uri_common.h +++ b/ext/uri/php_uri_common.h @@ -17,6 +17,8 @@ #ifndef PHP_URI_COMMON_H #define PHP_URI_COMMON_H +extern zend_class_entry *uri_rfc3986_uri_ce; +extern zend_object_handlers uri_rfc3986_uri_object_handlers; extern zend_class_entry *uri_whatwg_url_ce; extern zend_object_handlers uri_whatwg_uri_object_handlers; extern zend_class_entry *uri_comparison_mode_ce; @@ -121,6 +123,7 @@ static inline uri_internal_t *uri_internal_from_obj(const zend_object *object) { #define Z_URI_OBJECT_P(zv) uri_object_from_obj(Z_OBJ_P((zv))) #define Z_URI_INTERNAL_P(zv) uri_internal_from_obj(Z_OBJ_P((zv))) +#define URI_PARSER_RFC3986 "Uri\\Rfc3986\\Uri" #define URI_PARSER_WHATWG "Uri\\WhatWg\\Url" #define URI_SERIALIZED_PROPERTY_NAME "uri" diff --git a/ext/uri/php_uriparser.c b/ext/uri/php_uriparser.c new file mode 100644 index 0000000000000..8c84f6f3a285a --- /dev/null +++ b/ext/uri/php_uriparser.c @@ -0,0 +1,415 @@ +/* + +----------------------------------------------------------------------+ + | 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: Máté Kocsis | + +----------------------------------------------------------------------+ +*/ + +#include "php.h" +#include "php_uriparser.h" +#include "php_uri_common.h" +#include "Zend/zend_smart_str.h" +#include "Zend/zend_exceptions.h" + +static void uriparser_free_uri(void *uri); +static void throw_invalid_uri_exception(void); + +static inline size_t get_text_range_length(const UriTextRangeA *range) +{ + return range->afterLast - range->first; +} + +ZEND_ATTRIBUTE_NONNULL static void uriparser_copy_uri(UriUriA *new_uriparser_uri, const UriUriA *uriparser_uri) +{ + int result = uriCopyUriA(new_uriparser_uri, uriparser_uri); + ZEND_ASSERT(result == URI_SUCCESS); +} + +ZEND_ATTRIBUTE_NONNULL static UriUriA *get_normalized_uri(uriparser_uris_t *uriparser_uris) { + if (!uriparser_uris->normalized_uri_initialized) { + uriparser_copy_uri(&uriparser_uris->normalized_uri, &uriparser_uris->uri); + int result = uriNormalizeSyntaxExA(&uriparser_uris->normalized_uri, (unsigned int)-1); + ZEND_ASSERT(result == URI_SUCCESS); + uriparser_uris->normalized_uri_initialized = true; + } + + return &uriparser_uris->normalized_uri; +} + +ZEND_ATTRIBUTE_NONNULL static UriUriA *uriparser_read_uri(uriparser_uris_t *uriparser_uris, uri_component_read_mode_t read_mode) +{ + switch (read_mode) { + case URI_COMPONENT_READ_RAW: + return &uriparser_uris->uri; + case URI_COMPONENT_READ_NORMALIZED_ASCII: + ZEND_FALLTHROUGH; + case URI_COMPONENT_READ_NORMALIZED_UNICODE: + return get_normalized_uri(uriparser_uris); + EMPTY_SWITCH_DEFAULT_CASE() + } +} + +ZEND_ATTRIBUTE_NONNULL static zend_result uriparser_read_scheme(const uri_internal_t *internal_uri, uri_component_read_mode_t read_mode, zval *retval) +{ + UriUriA *uriparser_uri = uriparser_read_uri(internal_uri->uri, read_mode); + ZEND_ASSERT(uriparser_uri != NULL); + + if (uriparser_uri->scheme.first != NULL && uriparser_uri->scheme.afterLast != NULL) { + zend_string *str = zend_string_init(uriparser_uri->scheme.first, get_text_range_length(&uriparser_uri->scheme), false); + ZVAL_NEW_STR(retval, str); + } else { + ZVAL_NULL(retval); + } + + return SUCCESS; +} + +ZEND_ATTRIBUTE_NONNULL zend_result uriparser_read_userinfo(const uri_internal_t *internal_uri, uri_component_read_mode_t read_mode, zval *retval) +{ + UriUriA *uriparser_uri = uriparser_read_uri(internal_uri->uri, read_mode); + ZEND_ASSERT(uriparser_uri != NULL); + + if (uriparser_uri->userInfo.first != NULL && uriparser_uri->userInfo.afterLast != NULL) { + ZVAL_STRINGL(retval, uriparser_uri->userInfo.first, get_text_range_length(&uriparser_uri->userInfo)); + } else { + ZVAL_NULL(retval); + } + + return SUCCESS; +} + +ZEND_ATTRIBUTE_NONNULL static zend_result uriparser_read_username(const uri_internal_t *internal_uri, uri_component_read_mode_t read_mode, zval *retval) +{ + UriUriA *uriparser_uri = uriparser_read_uri(internal_uri->uri, read_mode); + ZEND_ASSERT(uriparser_uri != NULL); + + if (uriparser_uri->userInfo.first != NULL && uriparser_uri->userInfo.afterLast != NULL) { + size_t length = get_text_range_length(&uriparser_uri->userInfo); + const char *c = memchr(uriparser_uri->userInfo.first, ':', length); + + if (c == NULL && length > 0) { + ZVAL_STRINGL(retval, uriparser_uri->userInfo.first, length); + } else if (c != NULL && c - uriparser_uri->userInfo.first > 0) { + ZVAL_STRINGL(retval, uriparser_uri->userInfo.first, c - uriparser_uri->userInfo.first); + } else { + ZVAL_NULL(retval); + } + } else { + ZVAL_NULL(retval); + } + + return SUCCESS; +} + +ZEND_ATTRIBUTE_NONNULL static zend_result uriparser_read_password(const uri_internal_t *internal_uri, uri_component_read_mode_t read_mode, zval *retval) +{ + UriUriA *uriparser_uri = uriparser_read_uri(internal_uri->uri, read_mode); + ZEND_ASSERT(uriparser_uri != NULL); + + if (uriparser_uri->userInfo.first != NULL && uriparser_uri->userInfo.afterLast != NULL) { + const char *c = memchr(uriparser_uri->userInfo.first, ':', get_text_range_length(&uriparser_uri->userInfo)); + + if (c != NULL && uriparser_uri->userInfo.afterLast - c - 1 > 0) { + ZVAL_STRINGL(retval, c + 1, uriparser_uri->userInfo.afterLast - c - 1); + } else { + ZVAL_NULL(retval); + } + } else { + ZVAL_NULL(retval); + } + + return SUCCESS; +} + +ZEND_ATTRIBUTE_NONNULL static zend_result uriparser_read_host(const uri_internal_t *internal_uri, uri_component_read_mode_t read_mode, zval *retval) +{ + 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->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}; + + smart_str_appendc(&host_str, '['); + smart_str_appendl(&host_str, uriparser_uri->hostText.first, get_text_range_length(&uriparser_uri->hostText)); + smart_str_appendc(&host_str, ']'); + + ZVAL_NEW_STR(retval, smart_str_extract(&host_str)); + } else { + ZVAL_STRINGL(retval, uriparser_uri->hostText.first, get_text_range_length(&uriparser_uri->hostText)); + } + } else { + ZVAL_NULL(retval); + } + + return SUCCESS; +} + +ZEND_ATTRIBUTE_NONNULL static size_t str_to_int(const char *str, size_t len) +{ + size_t result = 0; + + for (size_t i = 0; i < len; ++i) { + result = result * 10 + (str[i] - '0'); + } + + return result; +} + +ZEND_ATTRIBUTE_NONNULL static zend_result uriparser_read_port(const uri_internal_t *internal_uri, uri_component_read_mode_t read_mode, zval *retval) +{ + UriUriA *uriparser_uri = uriparser_read_uri(internal_uri->uri, read_mode); + ZEND_ASSERT(uriparser_uri != NULL); + + if (uriparser_uri->portText.first != NULL && uriparser_uri->portText.afterLast != NULL) { + ZVAL_LONG(retval, str_to_int(uriparser_uri->portText.first, get_text_range_length(&uriparser_uri->portText))); + } else { + ZVAL_NULL(retval); + } + + return SUCCESS; +} + +ZEND_ATTRIBUTE_NONNULL static zend_result uriparser_read_path(const uri_internal_t *internal_uri, uri_component_read_mode_t read_mode, zval *retval) +{ + UriUriA *uriparser_uri = uriparser_read_uri(internal_uri->uri, read_mode); + ZEND_ASSERT(uriparser_uri != NULL); + + if (uriparser_uri->pathHead != NULL) { + smart_str str = {0}; + + if (uriparser_uri->absolutePath || uriHasHostA(uriparser_uri)) { + smart_str_appendc(&str, '/'); + } + + for (const UriPathSegmentA *p = uriparser_uri->pathHead; p; p = p->next) { + smart_str_appendl(&str, p->text.first, get_text_range_length(&p->text)); + if (p->next) { + smart_str_appendc(&str, '/'); + } + } + + ZVAL_NEW_STR(retval, smart_str_extract(&str)); + } else if (uriparser_uri->absolutePath) { + ZVAL_CHAR(retval, '/'); + } else { + ZVAL_EMPTY_STRING(retval); + } + + return SUCCESS; +} + +ZEND_ATTRIBUTE_NONNULL static zend_result uriparser_read_query(const uri_internal_t *internal_uri, uri_component_read_mode_t read_mode, zval *retval) +{ + UriUriA *uriparser_uri = uriparser_read_uri(internal_uri->uri, read_mode); + ZEND_ASSERT(uriparser_uri != NULL); + + if (uriparser_uri->query.first != NULL && uriparser_uri->query.afterLast != NULL) { + ZVAL_STRINGL(retval, uriparser_uri->query.first, get_text_range_length(&uriparser_uri->query)); + } else { + ZVAL_NULL(retval); + } + + return SUCCESS; +} + +ZEND_ATTRIBUTE_NONNULL static zend_result uriparser_read_fragment(const uri_internal_t *internal_uri, uri_component_read_mode_t read_mode, zval *retval) +{ + UriUriA *uriparser_uri = uriparser_read_uri(internal_uri->uri, read_mode); + ZEND_ASSERT(uriparser_uri != NULL); + + if (uriparser_uri->fragment.first != NULL && uriparser_uri->fragment.afterLast != NULL) { + ZVAL_STRINGL(retval, uriparser_uri->fragment.first, get_text_range_length(&uriparser_uri->fragment)); + } else { + ZVAL_NULL(retval); + } + + return SUCCESS; +} + +static void *uriparser_malloc(UriMemoryManager *memory_manager, size_t size) +{ + return emalloc(size); +} + +static void *uriparser_calloc(UriMemoryManager *memory_manager, size_t nmemb, size_t size) +{ + return ecalloc(nmemb, size); +} + +static void *uriparser_realloc(UriMemoryManager *memory_manager, void *ptr, size_t size) +{ + return erealloc(ptr, size); +} + +static void *uriparser_reallocarray(UriMemoryManager *memory_manager, void *ptr, size_t nmemb, size_t size) +{ + return safe_erealloc(ptr, nmemb, size, 0); +} + +static void uriparser_free(UriMemoryManager *memory_manager, void *ptr) +{ + efree(ptr); +} + +PHP_MINIT_FUNCTION(uri_uriparser) +{ + if (uri_handler_register(&uriparser_uri_handler) == FAILURE) { + return FAILURE; + } + + defaultMemoryManager.malloc = uriparser_malloc; + defaultMemoryManager.calloc = uriparser_calloc; + defaultMemoryManager.realloc = uriparser_realloc; + defaultMemoryManager.reallocarray = uriparser_reallocarray; + defaultMemoryManager.free = uriparser_free; + + return SUCCESS; +} + +static uriparser_uris_t *uriparser_create_uris(void) +{ + uriparser_uris_t *uriparser_uris = ecalloc(1, sizeof(*uriparser_uris)); + uriparser_uris->normalized_uri_initialized = false; + + 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 || \ + uriParseSingleUriExA(dest_uri, ZSTR_VAL(uri_str), ZSTR_VAL(uri_str) + ZSTR_LEN(uri_str), NULL) != 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(); + + if (uriparser_base_urls == NULL) { + PARSE_URI(&uriparser_uris->uri, uri_str, uriparser_uris, silent); + uriMakeOwnerA(&uriparser_uris->uri); + } else { + UriUriA uri; + + PARSE_URI(&uri, uri_str, uriparser_uris, silent); + + if (uriAddBaseUriA(&uriparser_uris->uri, &uri, &uriparser_base_urls->uri) != URI_SUCCESS) { + efree(uriparser_uris); + uriFreeUriMembersA(&uri); + if (!silent) { + throw_invalid_uri_exception(); + } + + return NULL; + } + + uriMakeOwnerA(&uriparser_uris->uri); + uriFreeUriMembersA(&uri); + } + + return uriparser_uris; +} + +void *uriparser_parse_uri(const zend_string *uri_str, const void *base_url, zval *errors, bool silent) +{ + return uriparser_parse_uri_ex(uri_str, base_url, silent); +} + +/* TODO make the clone handler accept a flag to distinguish between clone() calls and withers. + * When calling a wither successfully, the normalized URI is surely invalidated, therefore + * it doesn't make sense to copy it. In case of failure, an exception is thrown, and the URI object + * is discarded altogether. */ +ZEND_ATTRIBUTE_NONNULL static void *uriparser_clone_uri(void *uri) +{ + uriparser_uris_t *uriparser_uris = uri; + + uriparser_uris_t *new_uriparser_uris = uriparser_create_uris(); + uriparser_copy_uri(&new_uriparser_uris->uri, &uriparser_uris->uri); + if (uriparser_uris->normalized_uri_initialized) { + uriparser_copy_uri(&new_uriparser_uris->normalized_uri, &uriparser_uris->normalized_uri); + new_uriparser_uris->normalized_uri_initialized = true; + } + + return new_uriparser_uris; +} + +ZEND_ATTRIBUTE_NONNULL static zend_string *uriparser_uri_to_string(void *uri, uri_recomposition_mode_t recomposition_mode, bool exclude_fragment) +{ + uriparser_uris_t *uriparser_uris = uri; + UriUriA *uriparser_uri; + + if (recomposition_mode == URI_RECOMPOSITION_RAW_ASCII || recomposition_mode == URI_RECOMPOSITION_RAW_UNICODE) { + uriparser_uri = &uriparser_uris->uri; + } else { + uriparser_uri = get_normalized_uri(uriparser_uris); + } + + int charsRequired = 0; + int result = uriToStringCharsRequiredA(uriparser_uri, &charsRequired); + ZEND_ASSERT(result == URI_SUCCESS); + + charsRequired++; + + zend_string *uri_string = zend_string_alloc(charsRequired - 1, false); + result = uriToStringA(ZSTR_VAL(uri_string), uriparser_uri, charsRequired, NULL); + ZEND_ASSERT(result == URI_SUCCESS); + + if (exclude_fragment) { + const char *pos = zend_memrchr(ZSTR_VAL(uri_string), '#', ZSTR_LEN(uri_string)); + if (pos != NULL) { + uri_string = zend_string_truncate(uri_string, (pos - ZSTR_VAL(uri_string)), false); + } + } + + return uri_string; +} + +ZEND_ATTRIBUTE_NONNULL static void uriparser_free_uri(void *uri) +{ + uriparser_uris_t *uriparser_uris = uri; + + uriFreeUriMembersA(&uriparser_uris->uri); + uriFreeUriMembersA(&uriparser_uris->normalized_uri); + + efree(uriparser_uris); +} + +const uri_handler_t uriparser_uri_handler = { + .name = URI_PARSER_RFC3986, + .parse_uri = uriparser_parse_uri, + .clone_uri = uriparser_clone_uri, + .uri_to_string = uriparser_uri_to_string, + .free_uri = uriparser_free_uri, + { + .scheme = {.read_func = uriparser_read_scheme, .write_func = NULL}, + .username = {.read_func = uriparser_read_username, .write_func = NULL}, + .password = {.read_func = uriparser_read_password, .write_func = NULL}, + .host = {.read_func = uriparser_read_host, .write_func = NULL}, + .port = {.read_func = uriparser_read_port, .write_func = NULL}, + .path = {.read_func = uriparser_read_path, .write_func = NULL}, + .query = {.read_func = uriparser_read_query, .write_func = NULL}, + .fragment = {.read_func = uriparser_read_fragment, .write_func = NULL}, + } +}; diff --git a/ext/uri/php_uriparser.h b/ext/uri/php_uriparser.h new file mode 100644 index 0000000000000..5f1cc04570697 --- /dev/null +++ b/ext/uri/php_uriparser.h @@ -0,0 +1,38 @@ +/* + +----------------------------------------------------------------------+ + | 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: Máté Kocsis | + +----------------------------------------------------------------------+ +*/ + +#ifndef PHP_URIPARSER_H +#define PHP_URIPARSER_H + +#include +#include "uriparser/src/UriMemory.h" +#include "php_uri_common.h" + +extern const uri_handler_t uriparser_uri_handler; + +typedef struct uriparser_uris_t { + UriUriA uri; + UriUriA normalized_uri; + bool normalized_uri_initialized; +} uriparser_uris_t; + +PHP_MINIT_FUNCTION(uri_uriparser); + +zend_result uriparser_read_userinfo(const uri_internal_t *internal_uri, uri_component_read_mode_t read_mode, zval *retval); + +void *uriparser_parse_uri_ex(const zend_string *uri_str, const uriparser_uris_t *uriparser_base_url, bool silent); + +#endif diff --git a/ext/uri/tests/003.phpt b/ext/uri/tests/003.phpt index bcd6e417441c2..be607fd6cacef 100644 --- a/ext/uri/tests/003.phpt +++ b/ext/uri/tests/003.phpt @@ -5,12 +5,15 @@ uri --FILE-- --EXPECTF-- +NULL object(Uri\WhatWg\Url)#%d (%d) { ["scheme"]=> string(4) "http" @@ -29,4 +32,22 @@ object(Uri\WhatWg\Url)#%d (%d) { ["fragment"]=> string(6) "anchor" } +object(Uri\Rfc3986\Uri)#%d (%d) { + ["scheme"]=> + NULL + ["username"]=> + NULL + ["password"]=> + NULL + ["host"]=> + NULL + ["port"]=> + NULL + ["path"]=> + string(7) "/page:1" + ["query"]=> + NULL + ["fragment"]=> + NULL +} NULL diff --git a/ext/uri/tests/004.phpt b/ext/uri/tests/004.phpt index abbad59fee2e8..10e90dc584a8d 100644 --- a/ext/uri/tests/004.phpt +++ b/ext/uri/tests/004.phpt @@ -5,6 +5,14 @@ uri --FILE-- getMessage() . "\n"; +} + +var_dump(Uri\Rfc3986\Uri::parse("")); + try { new Uri\WhatWg\Url(""); } catch (Uri\WhatWg\InvalidUrlException $e) { @@ -13,13 +21,36 @@ try { var_dump(Uri\WhatWg\Url::parse("")); +var_dump(Uri\Rfc3986\Uri::parse("192.168/contact.html")); var_dump(Uri\WhatWg\Url::parse("192.168/contact.html", null)); +var_dump(Uri\Rfc3986\Uri::parse("http://RuPaul's Drag Race All Stars 7 Winners Cast on This Season's")); var_dump(Uri\WhatWg\Url::parse("http://RuPaul's Drag Race All Stars 7 Winners Cast on This Season's", null)); ?> ---EXPECT-- +--EXPECTF-- +The specified URI is malformed +NULL The specified URI is malformed (MissingSchemeNonRelativeUrl) NULL +object(Uri\Rfc3986\Uri)#%d (%d) { + ["scheme"]=> + NULL + ["username"]=> + NULL + ["password"]=> + NULL + ["host"]=> + NULL + ["port"]=> + NULL + ["path"]=> + string(20) "192.168/contact.html" + ["query"]=> + NULL + ["fragment"]=> + NULL +} +NULL NULL NULL diff --git a/ext/uri/tests/005.phpt b/ext/uri/tests/005.phpt index 262d43a75406b..6db6c4a56ee5a 100644 --- a/ext/uri/tests/005.phpt +++ b/ext/uri/tests/005.phpt @@ -5,6 +5,8 @@ uri --FILE-- getAsciiHost()); @@ -14,6 +16,7 @@ var_dump($url->toUnicodeString()); ?> --EXPECTF-- +NULL object(Uri\WhatWg\Url)#%d (%d) { ["scheme"]=> string(4) "http" diff --git a/ext/uri/tests/006.phpt b/ext/uri/tests/006.phpt index 0aba3e9e46b5e..c4da9db905c82 100644 --- a/ext/uri/tests/006.phpt +++ b/ext/uri/tests/006.phpt @@ -5,11 +5,32 @@ uri --FILE-- --EXPECTF-- +object(Uri\Rfc3986\Uri)#%d (%d) { + ["scheme"]=> + string(5) "https" + ["username"]=> + string(8) "username" + ["password"]=> + string(8) "password" + ["host"]=> + string(11) "example.com" + ["port"]=> + int(8080) + ["path"]=> + string(5) "/path" + ["query"]=> + string(3) "q=r" + ["fragment"]=> + string(8) "fragment" +} object(Uri\WhatWg\Url)#%d (%d) { ["scheme"]=> string(5) "https" diff --git a/ext/uri/tests/007.phpt b/ext/uri/tests/007.phpt index cb445fcf71a43..54151f2dfcb1c 100644 --- a/ext/uri/tests/007.phpt +++ b/ext/uri/tests/007.phpt @@ -5,6 +5,12 @@ uri --FILE-- getMessage() . "\n"; +} + try { new Uri\WhatWg\Url("https://example.com:8080@username:password/path?q=r#fragment"); } catch (Uri\WhatWg\InvalidUrlException $e) { @@ -19,6 +25,7 @@ var_dump($failures); ?> --EXPECTF-- +The specified URI is malformed The specified URI is malformed (PortInvalid) array(%d) { [0]=> diff --git a/ext/uri/tests/008.phpt b/ext/uri/tests/008.phpt index f4fddcd8eb777..e13130bb4c466 100644 --- a/ext/uri/tests/008.phpt +++ b/ext/uri/tests/008.phpt @@ -5,6 +5,27 @@ uri --FILE-- getScheme()); + var_dump($uri->getRawScheme()); + var_dump($uri->getUsername()); + var_dump($uri->getRawUsername()); + var_dump($uri->getPassword()); + var_dump($uri->getRawPassword()); + var_dump($uri->getUserInfo()); + var_dump($uri->getRawUserInfo()); + var_dump($uri->getHost()); + var_dump($uri->getRawHost()); + var_dump($uri->getPort()); + var_dump($uri->getPath()); + var_dump($uri->getRawPath()); + var_dump($uri->getQuery()); + var_dump($uri->getRawQuery()); + var_dump($uri->getFragment()); + var_dump($uri->getRawFragment()); +} + function callWhatWgGetters($url) { var_dump($url->getScheme()); @@ -18,11 +39,34 @@ function callWhatWgGetters($url) var_dump($url->getFragment()); } +$uri = Uri\Rfc3986\Uri::parse("https://username:password@www.google.com:8080/pathname1/pathname2/pathname3?query=true#hash-exists"); +callRfc3986Getters($uri); + +echo "\n"; + $url = Uri\WhatWg\Url::parse("https://username:password@www.google.com:8080/pathname1/pathname2/pathname3?query=true#hash-exists"); callWhatWgGetters($url); ?> --EXPECT-- +string(5) "https" +string(5) "https" +string(8) "username" +string(8) "username" +string(8) "password" +string(8) "password" +string(17) "username:password" +string(17) "username:password" +string(14) "www.google.com" +string(14) "www.google.com" +int(8080) +string(30) "/pathname1/pathname2/pathname3" +string(30) "/pathname1/pathname2/pathname3" +string(10) "query=true" +string(10) "query=true" +string(11) "hash-exists" +string(11) "hash-exists" + string(5) "https" string(8) "username" string(8) "password" diff --git a/ext/uri/tests/009.phpt b/ext/uri/tests/009.phpt index 1b279588c0167..05f2820bb3fcf 100644 --- a/ext/uri/tests/009.phpt +++ b/ext/uri/tests/009.phpt @@ -5,10 +5,29 @@ uri --FILE-- --EXPECTF-- +object(Uri\Rfc3986\Uri)#%d (%d) { + ["scheme"]=> + string(16) "chrome-extension" + ["username"]=> + NULL + ["password"]=> + NULL + ["host"]=> + string(11) "example.com" + ["port"]=> + NULL + ["path"]=> + string(0) "" + ["query"]=> + NULL + ["fragment"]=> + NULL +} object(Uri\WhatWg\Url)#%d (%d) { ["scheme"]=> string(16) "chrome-extension" diff --git a/ext/uri/tests/010.phpt b/ext/uri/tests/010.phpt index 4ec13f652f60c..2ca071eb2ca33 100644 --- a/ext/uri/tests/010.phpt +++ b/ext/uri/tests/010.phpt @@ -5,11 +5,49 @@ uri --FILE-- --EXPECTF-- +object(Uri\Rfc3986\Uri)#%d (%d) { + ["scheme"]=> + string(4) "http" + ["username"]=> + NULL + ["password"]=> + NULL + ["host"]=> + string(11) "example.com" + ["port"]=> + NULL + ["path"]=> + string(14) "/path/to/file2" + ["query"]=> + NULL + ["fragment"]=> + NULL +} +object(Uri\Rfc3986\Uri)#%d (%d) { + ["scheme"]=> + string(5) "https" + ["username"]=> + NULL + ["password"]=> + NULL + ["host"]=> + string(8) "test.com" + ["port"]=> + NULL + ["path"]=> + string(14) "/path/to/file2" + ["query"]=> + NULL + ["fragment"]=> + NULL +} object(Uri\WhatWg\Url)#%d (%d) { ["scheme"]=> string(4) "http" diff --git a/ext/uri/tests/011.phpt b/ext/uri/tests/011.phpt index 283886fb34fbb..49b915fa22a31 100644 --- a/ext/uri/tests/011.phpt +++ b/ext/uri/tests/011.phpt @@ -5,6 +5,12 @@ uri --FILE-- toRawString()); +var_dump(Uri\Rfc3986\Uri::parse("https://www.example.com/dir1/../dir2")->toRawString()); +var_dump(Uri\Rfc3986\Uri::parse("https://你好你好")); +var_dump(Uri\Rfc3986\Uri::parse("https://0Xc0.0250.01")); +var_dump(Uri\Rfc3986\Uri::parse("HttPs://0300.0250.0000.0001/path?query=foo%20bar")->toRawString()); + var_dump(Uri\WhatWg\Url::parse("http://////www.EXAMPLE.com:80")->toAsciiString()); var_dump(Uri\WhatWg\Url::parse("https://www.example.com:443/dir1/../dir2")->toAsciiString()); var_dump(Uri\WhatWg\Url::parse("https://你好你好")->toAsciiString()); @@ -14,6 +20,11 @@ var_dump(Uri\WhatWg\Url::parse("HttPs://0300.0250.0000.0001/path?query=foo%20bar ?> --EXPECT-- +string(29) "http://////www.EXAMPLE.com:80" +string(36) "https://www.example.com/dir1/../dir2" +NULL +NULL +string(48) "HttPs://0300.0250.0000.0001/path?query=foo%20bar" string(23) "http://www.example.com/" string(28) "https://www.example.com/dir2" string(23) "https://xn--6qqa088eba/" diff --git a/ext/uri/tests/012.phpt b/ext/uri/tests/012.phpt index 0784a74e625f0..7c14014fb3519 100644 --- a/ext/uri/tests/012.phpt +++ b/ext/uri/tests/012.phpt @@ -5,12 +5,32 @@ uri --FILE-- --EXPECTF-- +object(Uri\Rfc3986\Uri)#%d (%d) { + ["scheme"]=> + string(6) "mailto" + ["username"]=> + NULL + ["password"]=> + NULL + ["host"]=> + NULL + ["port"]=> + NULL + ["path"]=> + string(15) "Joe@Example.COM" + ["query"]=> + NULL + ["fragment"]=> + NULL +} object(Uri\WhatWg\Url)#%d (%d) { ["scheme"]=> string(6) "mailto" @@ -29,6 +49,24 @@ object(Uri\WhatWg\Url)#%d (%d) { ["fragment"]=> NULL } +object(Uri\Rfc3986\Uri)#%d (%d) { + ["scheme"]=> + string(4) "file" + ["username"]=> + NULL + ["password"]=> + NULL + ["host"]=> + NULL + ["port"]=> + NULL + ["path"]=> + string(30) "/E:/Documents%20and%20Settings" + ["query"]=> + NULL + ["fragment"]=> + NULL +} object(Uri\WhatWg\Url)#%d (%d) { ["scheme"]=> string(4) "file" diff --git a/ext/uri/tests/013.phpt b/ext/uri/tests/013.phpt index 016fe6632782c..6a5bb31870fb1 100644 --- a/ext/uri/tests/013.phpt +++ b/ext/uri/tests/013.phpt @@ -5,14 +5,39 @@ uri --FILE-- + @")); + var_dump(Uri\WhatWg\Url::parse("http://example.com?foobar=%27%3Cscript%3E+%2B+%40")); var_dump(Uri\WhatWg\Url::parse("http://example.com?foobar='